10 acc_nr::acc_nr(String &s)
14 std::cerr << "Account number from " << s;
18 std::cerr << " : " << *this << "\n";
21 acc_nr::operator String()
24 sprintf(_buf, "%03d.%02d", group, nr);
30 std::istream &operator>>(std::istream &s, acc_nr &a)
34 s >> a.group >> c >> a.nr;
38 std::ostream &operator<<(std::ostream &s, acc_nr a)
44 std::istream &operator>>(std::istream &s, amount &a)
49 s >> hundreds >> c >> a.value;
50 a.value += hundreds * 100;
55 std::ostream &operator<<(std::ostream &s, amount a)
61 s << std::setw(8) << std::setfill(' ') << a / 100 << ".";
62 s << std::setw(2) << std::setfill('0') << a % 100;
63 s << std::setw(0) << std::setfill(' ');
69 String amount::to_string()
72 sprintf(_buf, "%8lu.%02lu", value / 100, value % 100);
84 std::ostream &operator<<(std::ostream &s, balance b)
86 s << b.Debit << " " << b.Credit;
91 std::istream &operator>>(std::istream &s, Booking &b)
93 s >> b.Bnumber >> b.booked;
99 std::ostream &operator<<(std::ostream &s, Booking &b)
101 s << "#" << std::setw(4) << std::setfill('0') << b.Bnumber;
102 s << std::setw(0) << std::setfill(' ');
103 s << " " << b.booked << " ";
104 s << std::setfill(' ') << std::setw(58) << std::left << b.comment;
105 s << std::setw(0) << std::right ;
110 std::istream &operator>>(std::istream &s, Mutation &m)
115 while (s.get(c), c == ' ')
128 while (p > 0 && amnt[p] == ' ')
132 while (p > 0 && amnt[p] != ' ')
137 amnt = amnt(p, ~amnt - p);
138 int dot = amnt.index('.');
139 String cents = amnt(dot+1, 2);
140 a = long(amnt) * 100 + cents.dec();
143 m.bal = balance(a, 0);
145 m.bal = balance(0, a);
150 std::ostream &operator<<(std::ostream &s, Mutation &m)
152 s << "#" << std::setw(4) << std::setfill('0') << m.booking_nr;
153 s << std::setw(0) << std::setfill(' ');
154 s << " " << m.account << m.bal;
160 std::istream &operator>>(std::istream &s, Account &acc)
164 s >> acc.Anumber >> kind >> std::ws;
175 std::ostream &operator<<(std::ostream &s, Account &acc)
177 s << acc.Anumber << " " << std::setw(44) << std::left << acc.name;
178 s << std::setw(0) << std::right << " ";
184 std::ostream& operator<<(std::ostream &s, Ledger &l)
187 balance total, saldi;
188 balance EndBalance, Result;
190 s << l.nr_accs << " accounts in ledger:\n\n";
191 for (i=0; i<l.nr_accs; i++)
194 saldi += ~balance(l.accs[i]);
195 s << l.accs[i] << ~balance(l.accs[i]);
198 s << " " << ~balance(l.accs[i]);
199 EndBalance += ~balance(l.accs[i]);
203 s << ~balance(l.accs[i]);
204 Result += ~balance(l.accs[i]);
214 s << -profit << profit << "\n";
217 EndBalance += profit;
220 s << total << saldi << Result << EndBalance << "\n";
225 void PostScript_balans_layout(PostScript &ps, String header)
227 ps.Line(16, 595, 755, 595);
228 ps.Line(16, 580, 755, 580);
229 ps.Line(16, 40, 755, 40);
230 ps.Text(200, 582, header);
232 ps.Line( 16, 595, 16, 40);
233 ps.Line(755, 595, 755, 40);
235 ps.LineAttributes(0.2, 1.0, 0.0);
236 ps.Line(195, 580, 195, 40);
237 ps.Line(335, 580, 335, 40);
238 ps.Line(475, 580, 475, 40);
239 ps.Line(615, 580, 615, 40);
241 ps.LineAttributes(0.2, 2.0, 2.0);
242 ps.Line(265, 580, 265, 40);
243 ps.Line(405, 580, 405, 40);
244 ps.Line(545, 580, 545, 40);
245 ps.Line(685, 580, 685, 40);
248 void Ledger::accounts_report(const char * filename)
252 PostScript ps(filename);
255 for (i=0; i<nr_accs; i++)
257 accs[i].Postscript_sheet(ps);
260 catch (psexception &e)
262 std::cerr << "Error creating postscript output: " << e.what() << "\n";
266 void Ledger::saldi_report(const char * filename, date period_begin, date period_end)
270 PostScript ps(filename);
271 balance total, saldi;
272 balance EndBalance, Result;
277 String header("Saldibalans");
279 header += " " + companyname;
280 header += " van " + period_begin.format("%e %B %Y") + " tot " + period_end.format("%e %B %Y");
282 ps.NewPage(842, 595);
286 for (i=0; i<nr_accs; i++)
288 balance saldo(accs[i]);
290 if (saldo.debit() != 0 || saldo.credit() != 0)
295 PostScript_balans_layout(ps, header);
296 ps.NewPage(842, 595);
304 ps.Rectangle(16, y-2, 739, 7);
308 saldi += ~balance(accs[i]);
310 ps.Text(20, y, String(accs[i].Number()));
311 ps.Text(50, y, accs[i].Name());
313 balance saldo(accs[i]);
315 ps.Text(200, y, saldo.debit().to_string());
316 ps.Text(270, y, saldo.credit().to_string());
318 ps.Text(340, y, saldo.debit().to_string());
319 ps.Text(410, y, saldo.credit().to_string());
323 EndBalance += ~balance(accs[i]);
325 ps.Text(620, y, saldo.debit().to_string());
326 ps.Text(690, y, saldo.credit().to_string());
330 Result += ~balance(accs[i]);
332 ps.Text(480, y, saldo.debit().to_string());
333 ps.Text(550, y, saldo.credit().to_string());
342 PostScript_balans_layout(ps, header);
347 EndBalance += profit;
349 ps.LineAttributes(0.5, 1.0, 0.0);
350 ps.Line(16, 60, 755, 60);
352 ps.Text(50, y, "Resultaat");
353 ps.Text(480, y, (-profit).debit().to_string());
354 ps.Text(550, y, (-profit).credit().to_string());
355 ps.Text(620, y, profit.debit().to_string());
356 ps.Text(690, y, profit.credit().to_string());
358 ps.Line(16, 50, 755, 50);
360 ps.Text(50, y, "Totaal");
361 ps.Text(200, y, total.debit().to_string());
362 ps.Text(270, y, total.credit().to_string());
363 ps.Text(340, y, saldi.debit().to_string());
364 ps.Text(410, y, saldi.credit().to_string());
365 ps.Text(480, y, Result.debit().to_string());
366 ps.Text(550, y, Result.credit().to_string());
367 ps.Text(620, y, EndBalance.debit().to_string());
368 ps.Text(690, y, EndBalance.credit().to_string());
370 catch (psexception &e)
372 std::cerr << "Error creating postscript output: " << e.what() << "\n";
376 void Ledger::XML_saldi(std::ostream &s, date period_begin, date period_end)
380 s << "<?xml version='1.0'?>\n";
381 s << "<accounting companyname='" << companyname << "'>\n";
382 s << "<balance-sheet begin='" << period_begin << "' end='" << period_end << "'>\n";
383 for (i=0; i<nr_accs; i++)
385 balance saldo = ~balance(accs[i]);
387 if (saldo.debit() != 0 || saldo.credit() != 0)
390 s << " <number>" << accs[i].Number() << "</number>\n";
391 s << " <name>" << accs[i].Name() << "</name>\n";
394 s << " <type>BALANCE</type>\n";
398 s << " <type>COST</type>\n";
400 if (saldo.debit() == 0)
402 s << " <balance>CREDIT</balance>\n";
403 s << " <amount>" << saldo.credit() << "</amount>\n";
407 s << " <balance>DEBIT</balance>\n";
408 s << " <amount>" << saldo.debit() << "</amount>\n";
410 s << " </account>\n";
414 s << "</balance-sheet>\n";
415 s << "</accounting>\n";
418 Account & Ledger::operator[](acc_nr Anr)
422 for (i=0; accs[i] != Anr && i<nr_accs; i++);
424 std::cerr << "Account " << Anr << " not found.\n";
432 void PostScript_account_layout(PostScript &ps)
434 ps.LineAttributes(1.0, 1.0, 0.0);
435 ps.Line(30, 770, 580, 770);
436 ps.Line(30, 740, 580, 740);
437 ps.Line(30, 20, 580, 20);
439 ps.Line(30, 770, 30, 20);
440 ps.Line(580, 770, 580, 20);
442 ps.LineAttributes(0.2, 1.0, 0.0);
443 ps.Line(400, 740, 400, 20);
444 ps.LineAttributes(0.2, 2.0, 2.0);
445 ps.Line(480, 740, 480, 20);
448 void Account::Postscript_sheet(PostScript &ps)
455 bool page_started = false;
459 /* Go through all mutations, selecting for each account */
461 for (M = 0; M < n_m; M++)
463 std::ostringstream bookstr;
465 if (acc_nr(m[M]) == Anumber)
471 PostScript_account_layout(ps);
474 ps.NewPage(596, 842);
477 ps.Text(40, 750, String(Anumber));
478 ps.Text(100, 750, name);
490 ps.Rectangle(30, y-2, 550, 9);
492 /* Search the booking date and description */
494 for (B = 0; b[B].number() != m[M].number(); B++);
496 ps.Text(40, y, bookstr.str().c_str());
498 ps.Text(400, y, saldo.debit().to_string());
499 ps.Text(480, y, saldo.credit().to_string());
506 /* Print the footer with the totals */
511 ps.Text(100, 50, "SALDO");
513 ps.Text(400, 50, saldo.debit().to_string());
514 ps.Text(480, 50, saldo.credit().to_string());
515 ps.Line(30, 40, 580, 40);
517 ps.Text(100, 30, "TOTAAL");
518 ps.Text(400, 30, total.debit().to_string());
519 ps.Text(480, 30, total.credit().to_string());
520 PostScript_account_layout(ps);
524 void Account::sheet(std::ostream &s)
529 s << "\n\n " << Anumber << " " << name << "\n";
530 s << "================================================================";
531 s << "===========+=============+===========+\n";
533 /* Go through all mutations, selecting for each account */
535 for (M = 0; M < n_m; M++)
537 if (acc_nr(m[M]) == Anumber)
541 /* Search the booking date and description */
543 for (B = 0; b[B].number() != m[M].number(); B++);
544 s << b[B] << "|" << balance(m[M]) << " |\n";
548 /* Print the footer with the totals */
551 s << " |" << -~total << " |\n";
552 s << "----------------------------------------------------------------";
553 s << "-----------+-------------+-----------+\n";
556 s << " |" << total << " |\n";
557 s << "----------------------------------------------------------------";
558 s << "-----------+-------------+-----------+\n";
561 void Ledger::read(char *filename)
563 std::ifstream in(filename);
569 std::cerr << "Cannot read ledger file" << filename << "\n";
578 if (isdigit(line_begin))
580 in.putback(line_begin);
584 else if (line_begin == '$')
586 // Optional attributes
588 String a_name, a_value;
592 int separator = attribute.index('=');
597 while (isspace(attribute[separator]));
598 a_name = attribute(0, separator+1);
600 separator = attribute.index('=');
605 while (isspace(attribute[separator]));
607 a_value(0, separator) = "";
609 if (a_name == "companyname")
611 companyname = a_value;
615 std::cerr << "Unrecognized attribute in Ledger: " << a_name << "\n";
618 else if (line_begin == '\n')
620 // Ignore empty lines
624 // Anything else is comment: eat it.
630 accs[nr_accs].Name() = String("Rekening bestaat niet");