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 << form("%8d.%02d",a / 100, a % 100);
62 s << std::setw(8) << a / 100 << ".";
63 s << std::setw(2) << std::setfill('0') << a % 100;
64 s << std::setw(0) << std::setfill(' ');
70 String amount::to_string()
73 sprintf(_buf, "%8lu.%02lu", value / 100, value % 100);
85 std::ostream &operator<<(std::ostream &s, balance b)
87 s << b.Debit << " " << b.Credit;
92 std::istream &operator>>(std::istream &s, Booking &b)
96 s >> b.Bnumber >> b.booked;
104 std::ostream &operator<<(std::ostream &s, Booking &b)
106 //s << form("#%03d ",b.Bnumber) << b.booked << " " << b.comment;
107 //s << form("%.*s", 58 - ~b.comment, " ");
108 s << "#" << std::setw(4) << std::setfill('0') << b.Bnumber;
109 s << std::setw(0) << std::setfill(' ');
110 s << " " << b.booked << " ";
111 s << std::setfill(' ') << std::setw(58) << std::left << b.comment;
112 s << std::setw(0) << std::right ;
117 std::istream &operator>>(std::istream &s, Mutation &m)
123 while (s.get(c), c == ' ')
132 //std::istringstream amnt(buf+strlen(buf)-10);
140 while (p > 0 && amnt[p] == ' ')
144 while (p > 0 && amnt[p] != ' ')
149 amnt = amnt(p, ~amnt - p);
150 int dot = amnt.index('.');
151 String cents = amnt(dot+1, 2);
152 a = long(amnt) * 100 + cents.dec();
155 m.bal = balance(a, 0);
157 m.bal = balance(0, a);
162 std::ostream &operator<<(std::ostream &s, Mutation &m)
164 s << "#" << std::setw(4) << std::setfill('0') << m.booking_nr;
165 s << std::setw(0) << std::setfill(' ');
166 s << " " << m.account << m.bal;
172 std::istream &operator>>(std::istream &s, Account &acc)
174 char kind, name[128];
176 s >> acc.Anumber >> kind >> std::ws;
190 std::ostream &operator<<(std::ostream &s, Account &acc)
192 s << acc.Anumber << " " << std::setw(44) << std::left << acc.name;
193 s << std::setw(0) << std::right << " ";
194 //s << form("%.*s", 45 - ~acc.name, " ");
200 std::ostream& operator<<(std::ostream &s, Ledger &l)
203 balance total, saldi;
204 balance EndBalance, Result;
206 s << l.nr_accs << " accounts in ledger:\n\n";
207 for (i=0; i<l.nr_accs; i++)
210 saldi += ~balance(l.accs[i]);
211 s << l.accs[i] << ~balance(l.accs[i]);
214 s << " " << ~balance(l.accs[i]);
215 EndBalance += ~balance(l.accs[i]);
219 s << ~balance(l.accs[i]);
220 Result += ~balance(l.accs[i]);
230 s << -profit << profit << "\n";
233 EndBalance += profit;
236 s << total << saldi << Result << EndBalance << "\n";
241 void PostScript_balans_layout(PostScript &ps, String header)
243 ps.Line(16, 595, 755, 595);
244 ps.Line(16, 580, 755, 580);
245 ps.Line(16, 40, 755, 40);
246 ps.Text(200, 582, header);
248 ps.Line( 16, 595, 16, 40);
249 ps.Line(755, 595, 755, 40);
251 ps.LineAttributes(0.2, 1.0, 0.0);
252 ps.Line(195, 580, 195, 40);
253 ps.Line(335, 580, 335, 40);
254 ps.Line(475, 580, 475, 40);
255 ps.Line(615, 580, 615, 40);
257 ps.LineAttributes(0.2, 2.0, 2.0);
258 ps.Line(265, 580, 265, 40);
259 ps.Line(405, 580, 405, 40);
260 ps.Line(545, 580, 545, 40);
261 ps.Line(685, 580, 685, 40);
264 void Ledger::accounts_report(const char * filename)
266 PostScript ps(filename);
269 for (i=0; i<nr_accs; i++)
271 accs[i].Postscript_sheet(ps);
275 void Ledger::saldi_report(const char * filename, date period_begin, date period_end)
277 PostScript ps(filename);
278 balance total, saldi;
279 balance EndBalance, Result;
284 String header("Saldibalans");
286 header += " van " + period_begin.format("%e %B %Y") + " tot " + period_end.format("%e %B %Y");
288 ps.NewPage(842, 595);
292 for (i=0; i<nr_accs; i++)
294 balance saldo(accs[i]);
296 if (saldo.debit() != 0 || saldo.credit() != 0)
301 PostScript_balans_layout(ps, header);
302 ps.NewPage(842, 595);
310 ps.Rectangle(16, y-2, 739, 7);
314 saldi += ~balance(accs[i]);
316 ps.Text(20, y, String(accs[i].Number()));
317 ps.Text(50, y, accs[i].Name());
319 balance saldo(accs[i]);
321 ps.Text(200, y, saldo.debit().to_string());
322 ps.Text(270, y, saldo.credit().to_string());
324 ps.Text(340, y, saldo.debit().to_string());
325 ps.Text(410, y, saldo.credit().to_string());
329 EndBalance += ~balance(accs[i]);
331 ps.Text(620, y, saldo.debit().to_string());
332 ps.Text(690, y, saldo.credit().to_string());
336 Result += ~balance(accs[i]);
338 ps.Text(480, y, saldo.debit().to_string());
339 ps.Text(550, y, saldo.credit().to_string());
348 PostScript_balans_layout(ps, header);
353 EndBalance += profit;
355 ps.LineAttributes(0.5, 1.0, 0.0);
356 ps.Line(16, 60, 755, 60);
358 ps.Text(50, y, "Resultaat");
359 ps.Text(480, y, (-profit).debit().to_string());
360 ps.Text(550, y, (-profit).credit().to_string());
361 ps.Text(620, y, profit.debit().to_string());
362 ps.Text(690, y, profit.credit().to_string());
364 ps.Line(16, 50, 755, 50);
366 ps.Text(50, y, "Totaal");
367 ps.Text(200, y, total.debit().to_string());
368 ps.Text(270, y, total.credit().to_string());
369 ps.Text(340, y, saldi.debit().to_string());
370 ps.Text(410, y, saldi.credit().to_string());
371 ps.Text(480, y, Result.debit().to_string());
372 ps.Text(550, y, Result.credit().to_string());
373 ps.Text(620, y, EndBalance.debit().to_string());
374 ps.Text(690, y, EndBalance.credit().to_string());
377 void Ledger::XML_saldi(std::ostream &s, date period_begin, date period_end)
381 s << "<?xml version='1.0'?>\n";
382 s << "<accounting companyname='" << companyname << "'>\n";
383 s << "<balance-sheet begin='" << period_begin << "' end='" << period_end << "'>\n";
384 for (i=0; i<nr_accs; i++)
386 balance saldo = ~balance(accs[i]);
388 if (saldo.debit() != 0 || saldo.credit() != 0)
391 s << " <number>" << accs[i].Number() << "</number>\n";
392 s << " <name>" << accs[i].Name() << "</name>\n";
395 s << " <type>BALANCE</type>\n";
399 s << " <type>COST</type>\n";
401 if (saldo.debit() == 0)
403 s << " <balance>CREDIT</balance>\n";
404 s << " <amount>" << saldo.credit() << "</amount>\n";
408 s << " <balance>DEBIT</balance>\n";
409 s << " <amount>" << saldo.debit() << "</amount>\n";
411 s << " </account>\n";
415 s << "</balance-sheet>\n";
416 s << "</accounting>\n";
419 Account & Ledger::operator[](acc_nr Anr)
423 for (i=0; accs[i] != Anr && i<nr_accs; i++);
425 std::cerr << "Account " << Anr << " not found.\n";
433 void PostScript_account_layout(PostScript &ps)
435 ps.LineAttributes(1.0, 1.0, 0.0);
436 ps.Line(30, 770, 580, 770);
437 ps.Line(30, 740, 580, 740);
438 ps.Line(30, 20, 580, 20);
440 ps.Line(30, 770, 30, 20);
441 ps.Line(580, 770, 580, 20);
443 ps.LineAttributes(0.2, 1.0, 0.0);
444 ps.Line(400, 740, 400, 20);
445 ps.LineAttributes(0.2, 2.0, 2.0);
446 ps.Line(480, 740, 480, 20);
449 void Account::Postscript_sheet(PostScript &ps)
456 bool page_started = false;
460 /* Go through all mutations, selecting for each account */
462 for (M = 0; M < n_m; M++)
464 std::ostringstream bookstr;
466 if (acc_nr(m[M]) == Anumber)
472 PostScript_account_layout(ps);
475 ps.NewPage(596, 842);
478 ps.Text(40, 750, String(Anumber));
479 ps.Text(100, 750, name);
491 ps.Rectangle(30, y-2, 550, 9);
493 /* Search the booking date and description */
495 for (B = 0; b[B].number() != m[M].number(); B++);
497 ps.Text(40, y, bookstr.str().c_str());
499 ps.Text(400, y, saldo.debit().to_string());
500 ps.Text(480, y, saldo.credit().to_string());
504 //s << b[B] << "|" << balance(m[M]) << " |\n";
508 /* Print the footer with the totals */
512 s << " |" << -~total << " |\n";
513 s << "----------------------------------------------------------------";
514 s << "-----------+-------------+-----------+\n";
517 s << " |" << total << " |\n";
518 s << "----------------------------------------------------------------";
519 s << "-----------+-------------+-----------+\n";
524 ps.Text(100, 50, "SALDO");
526 ps.Text(400, 50, saldo.debit().to_string());
527 ps.Text(480, 50, saldo.credit().to_string());
528 ps.Line(30, 40, 580, 40);
530 ps.Text(100, 30, "TOTAAL");
531 ps.Text(400, 30, total.debit().to_string());
532 ps.Text(480, 30, total.credit().to_string());
533 PostScript_account_layout(ps);
537 void Account::sheet(std::ostream &s)
542 s << "\n\n " << Anumber << " " << name << "\n";
543 s << "================================================================";
544 s << "===========+=============+===========+\n";
546 /* Go through all mutations, selecting for each account */
548 for (M = 0; M < n_m; M++)
550 if (acc_nr(m[M]) == Anumber)
554 /* Search the booking date and description */
556 for (B = 0; b[B].number() != m[M].number(); B++);
557 s << b[B] << "|" << balance(m[M]) << " |\n";
561 /* Print the footer with the totals */
564 s << " |" << -~total << " |\n";
565 s << "----------------------------------------------------------------";
566 s << "-----------+-------------+-----------+\n";
569 s << " |" << total << " |\n";
570 s << "----------------------------------------------------------------";
571 s << "-----------+-------------+-----------+\n";
574 void Ledger::read(char *filename)
576 std::ifstream in(filename);
582 std::cerr << "Cannot read ledger file" << filename << "\n";
590 if (isdigit(line_begin))
592 in.putback(line_begin);
596 else if (line_begin == '$')
598 // Optional attributes
600 String a_name, a_value;
604 int separator = attribute.index('=');
609 while (isspace(attribute[separator]));
610 a_name = attribute(0, separator+1);
612 separator = attribute.index('=');
617 while (isspace(attribute[separator]));
619 a_value(0, separator) = "";
621 if (a_name == "companyname")
623 companyname = a_value;
627 std::cerr << "Unrecognized attribute in Ledger: " << a_name << "\n";
630 else if (line_begin == '\n')
632 // Ignore empty lines
636 // Anything else is comment: eat it.
642 accs[nr_accs].Name() = String("Rekening bestaat niet");