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; }
/* * 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; }