void
BalanceSheetReport::display_body()
{
    // Assume m_balance_map is up-to-date. Use its contents to display
    // the report contents.
    
    // TODO MEDIUM PRIORITY Can we just ignore equity Accounts here?

    increment_row();

    display_text(wxString("Opening balance "), 2, wxALIGN_RIGHT);
    display_text(wxString("  Movement "), 3, wxALIGN_RIGHT);
    display_text(wxString("  Closing balance "), 4, wxALIGN_RIGHT);

    increment_row();
    
    list<wxString> asset_names;
    list<wxString> equity_names;
    list<wxString> liability_names;

    for (auto const& elem: m_balance_map)
    {
        Handle<Account> const account(database_connection(), elem.first);
        wxString const name = account->name();
        switch (account->account_type())
        {
        case AccountType::asset:
            asset_names.push_back(name);
            break;
        case AccountType::liability:
            liability_names.push_back(name);
            break;
        case AccountType::equity:
            equity_names.push_back(name);
            break;
        default:
            JEWEL_HARD_ASSERT (false);
        }
    }
    asset_names.sort();
    equity_names.sort();
    liability_names.sort();

    vector<wxString> section_titles;
    section_titles.push_back(wxString("ASSETS"));

    // TODO LOW PRIORITY Assuming no Equity Account. Do an assertion
    // to this effect.
    section_titles.push_back(wxString("LIABILITIES"));
    vector<AccountType> section_account_types;
    section_account_types.push_back(AccountType::asset);
    section_account_types.push_back(AccountType::liability);
    JEWEL_ASSERT (section_titles.size() == section_account_types.size());

    Decimal const zero
    (   0,
        database_connection().default_commodity()->precision()
    );
    Decimal net_assets_opening = zero;
    Decimal net_assets_closing = zero;
    for (vector<wxString>::size_type i = 0 ; i != section_titles.size(); ++i)
    {
        // TODO LOW PRIORITY This relies on every Account having the same
        // Commodity. Do an assertion to this effect.
        Decimal opening_balance_total = zero;
        Decimal closing_balance_total = zero;
        list<wxString>* names = 0;
        switch(section_account_types.at(i))
        {
        case AccountType::asset:
            names = &asset_names;
            break;
        case AccountType::liability:
            names = &liability_names;
            break;
        default:
            JEWEL_HARD_ASSERT (false);
        }
        display_text(section_titles.at(i), 1);
        
        increment_row();

        JEWEL_ASSERT (names);
        for (wxString const& name: *names)
        {
            Handle<Account> const account
            (   database_connection(),
                Account::id_for_name(database_connection(), name)
            );
            BalanceMap::const_iterator const jt =
                m_balance_map.find(account->id());
            JEWEL_ASSERT (jt != m_balance_map.end());
            BalanceDatum const& datum = jt->second;
            Decimal const& ob = datum.opening_balance;
            Decimal const& cb = datum.closing_balance;

            // Only show Accounts with non-zero balances
            if ((ob != zero) || (cb != zero))
            {
                display_text(name, 1);
                display_decimal(ob, 2);
                display_decimal(cb - ob, 3);
                display_decimal(cb, 4);
                opening_balance_total += ob;
                closing_balance_total += cb;

                increment_row();
            }
        }
        display_text(wxString("  Total"), 1);
        display_decimal(opening_balance_total, 2);
        display_decimal(closing_balance_total - opening_balance_total, 3);
        display_decimal(closing_balance_total, 4);
        net_assets_opening += opening_balance_total;
        net_assets_closing += closing_balance_total;

        increment_row();
        increment_row();
    }

    display_text(wxString("  Net assets"), 1);
    display_decimal(net_assets_opening, 2);
    display_decimal(net_assets_closing - net_assets_opening, 3);
    display_decimal(net_assets_closing, 4);

    increment_row();

    return;
}
Beispiel #2
0
/*
 * terminal_read
 *   DESCRIPTION:	Reads nbytes from the terminal and enters them into buf.  Reads up to nbytes or new line or null character.
 *   INPUTS: 		buf - buffer to fill
 *					nbytes - number of bytes to read
 *   OUTPUTS: 		none
 *   RETURN VALUE:	number of bytes actually read, -1 on error
 *   SIDE EFFECTS:	Modifies buf
 */
int32_t terminal_read(void* buf, int32_t nbytes){
	
	sti();
	
	//Check for valid buf
	if(buf == 0x0)
	{
		return -1;
	}
	
	//Clear the read buffer
	*t_pos = 0;
	int i;
	for (i = 0; i < 1024; i++)
	{
		terminal_buffer[i] = '\0';
	}
	
	//Read until enter is pressed
	*enter_pressed = 0;
	*isReading = 1;
	while(!(*enter_pressed))
	{
		//Wait for enter to be pressed
		terminal_clear();
	}
	*isReading = 0;
	
	//Fill buf with the terminal's read buffer
	int j = 0;
	for(i=0; i<nbytes; i++){
		j++;
		if(terminal_buffer[i] == '\n'){
			//found new line
			i++;
			break;
		}
		if(terminal_buffer[i] == '\0'){
			j--;
		}
		((char *)buf)[i] = terminal_buffer[i];
		
		if (j >= 72)
		{
			if (j == 72)
				increment_row();
			else if ((j-72)%80 == 0)
				increment_row();
		}
	}
	((char *)buf)[i] = '\0';     //terminating string character
	
	*t_pos = 0;
	for (i = 0; i < 1024; i++)
	{
		terminal_buffer[i] = '\0';
	}
	
	increment_row();
	
	//Return the number of bytes put into buf
	return i+1;
}