Added loan and interest calculations
[account.git] / account_main.cpp
1 #include "account.h"
2 #include <fstream>
3 #include <iomanip>
4 #include <getopt.h>
5
6 static char  helptext[] = 
7      "Usage: account [options] journal\n"
8      "\n"
9      "Options:\n"
10      "  -r <start>\n"
11      "  --renumber <start>   :  Renumber the booking numbers (start > 0)\n"
12      "  --help               :  Print this helpful message\n"
13      "  -V\n"
14      "  --version            :  Print the version number\n";
15
16 void read_journal(char *journal_file);
17 void renumber_journal(char *journal_file, unsigned long renumber);
18 void print_journal();
19
20 Ledger    ledger;
21 Booking   b[40000];
22 Mutation  m[200000];
23
24 int n_m = 0, n_b = 0;
25
26 static struct option long_options[] =
27 {
28    { "help",       no_argument,        0,   'h' },
29    { "renumber",   required_argument,  0,   'r' },
30    { "version",    no_argument,        0,   'V' },
31    { 0, 0, 0, 0 }
32 };
33
34 int main(int argc, char *argv[])
35 {
36    int      i, c;
37    Account  a;
38
39    unsigned long renum = 0;
40
41    int      option_index = 0;
42
43    while ((c = getopt_long(argc, argv, "Vr:", long_options, &option_index)) != -1)
44    {
45       switch (c)
46       {
47       case 'h':
48          std::cout << helptext;
49          exit(0);
50          break;
51
52       case 'V':
53          std::cout << "account version 1.4\n";
54          exit(0);
55          break;
56
57       case 'r':
58          renum = String(optarg);
59          break;
60       }
61    }
62
63    if (optind == argc)
64    {
65       std::cerr << "Usage: account [options] journal_file\n";
66       exit(1);
67    }
68
69    if (renum != 0)
70    {
71       renumber_journal(argv[optind], renum);
72       exit(0);
73    }
74
75    ledger.read((char *)"Ledger");
76    read_journal(argv[optind]);
77
78
79    ledger.start();
80
81    while (a = ledger.next(), a != acc_nr(1000, 1000))
82       a.sheet(std::cout);
83
84    ledger.accounts_report("grootboek.ps");
85
86    //   Calculate all accounts to create the final balance.
87
88    for (i = 0; i < n_m; i++)
89       ledger[m[i]] += m[i];
90
91    std::cout << ledger;
92    
93    ledger.saldi_report("saldibalans.ps", date(b[0]), date(b[n_b-1]));
94
95    std::ofstream  saldi("saldi.xml");
96    ledger.XML_saldi(saldi, date(b[0]), date(b[n_b-1]));
97
98    return 0;
99 }
100
101 void read_journal(char *journal_file)
102 {
103    Booking    B;
104    balance    bal;
105    Mutation   M[100];
106
107    int        n_mut = 0;
108    char       first_char;
109
110    std::ifstream  i(journal_file);
111
112    while (i)
113    {
114       first_char = '\n';
115       i.get(first_char);
116       switch (first_char)
117       {
118       case '#' :
119          if (n_mut != 0)
120          {
121             if (bal)
122             {
123                if (n_b > 0)
124                {
125                   if (date(B) < date(b[n_b - 1]))
126                   {
127                      std::cerr << "The date of booking " << B.number() << " is out of sequence.\n";
128                   }
129                   if (B.number() < b[n_b - 1].number())
130                   {
131                      std::cerr << "The number of booking " << B.number() << " is out of sequence.\n";
132                   }
133                }
134                b[n_b++] = B;
135                for (int j = 0; j < n_mut; j++)
136                   m[n_m++] = M[j];
137             }
138             else
139             {
140                std::cerr << "Booking nr. " << B.number()
141                     << " is out of balance: " << bal << "\n";
142             }
143             n_mut = 0;
144             bal = balance(0,0);
145             //std::cerr << "\n";
146          }
147          i >> B;
148          //std::cerr << B << "\n";  //  Provide visual check
149          break;
150
151       case ' ' :
152          M[n_mut] = Mutation(B.number());
153          i >> M[n_mut];
154          //std::cerr << "  > " << M[n_mut] << "\n";   // Provide visual check
155          if (i.good())
156          {
157             bal += M[n_mut];
158             n_mut++;
159          }
160          else
161          {
162             std::cerr << "Input error at #" << B.number() << "\n";
163             i.clear();
164          }
165          break;
166
167       case '\n' :  break;   // Ignore linefeeds
168       default:     break;
169       }
170    }
171
172    if (n_mut != 0)
173    {
174       if (bal)
175       {
176          b[n_b++] = B;
177          for (int j = 0; j < n_mut; j++)
178             m[n_m++] = M[j];
179       }
180    }
181 }
182
183 void renumber_journal(char *journal_file, unsigned long renumber)
184 {
185    std::ifstream  i(journal_file);
186    String         line;
187
188    bool          started = false;
189
190    while (i >> line)
191    {
192       if (line[0] == '#')
193       {
194          int    c  = line.index(' ');
195          String nr = line(1,c-1);
196          unsigned long b_nr = nr.dec();
197          line(0,c) = String("");
198
199          if (started)
200          {
201             b_nr = renumber++;
202          }
203          else
204          {
205             if (b_nr == renumber)
206             {
207                renumber ++;
208                started = true;
209             }
210          }
211          std::cout << "#" << std::setw(4) << std::setfill('0') << b_nr;
212          std::cout << line << "\n";
213       }
214       else
215       {
216          std::cout << line << "\n";
217       }
218    }
219 }
220
221 void print_journal()
222 {
223    for (int mi = 0; mi < n_m; mi++)
224    {
225       std::cout << m[mi] << "\n";
226    }
227 }