Added loan and interest calculations
[account.git] / loan.cpp
1
2 #include "account.h"
3
4 #include <fstream>
5 #include <iomanip>
6 #include <list>
7 #include <getopt.h>
8
9 //  Not used but referred to from account.cpp
10
11 Booking   b[4];
12 Mutation  m[20];
13
14 int n_m = 0, n_b = 0;
15
16 /*
17  *  A Loan is list of transactions. each transaction is a date and a balance.
18  *  The balance states the amount added to de loan (Debit) or payed back (Credit).
19  */
20
21 //----------------------------transaction---------------------
22
23 class transaction
24 {
25 public:
26
27    date     booked;
28    balance  mutation;
29
30    friend std::istream & operator>>(std::istream &, transaction &);
31    friend std::ostream & operator<<(std::ostream &, transaction );
32 };
33
34 std::istream &operator>>(std::istream &s, transaction &t)
35 {
36    amount debit, credit;
37
38    s >> t.booked;
39    s >> debit >> credit;
40    t.mutation = balance(debit, credit);
41
42    return s;
43 }
44
45 std::ostream & operator<<(std::ostream &s, transaction t)
46 {
47    s << t.booked << " " << t.mutation;
48
49    return s;
50 }
51
52 //----------------------------loan----------------------------
53
54 class loan
55 {
56    std::list<transaction>   records;
57
58 public:
59
60    void read(char *filename);
61    void report();
62 };
63
64 void loan::read(char *filename)
65 {
66    std::ifstream  in(filename);
67
68    while (in)
69    {
70       transaction tr;
71       in >> tr;
72
73       if (in)
74       {
75          records.push_back(tr);
76       }
77    }
78 }
79
80 void loan::report()
81 {
82    std::list<transaction>::const_iterator  ri;
83    transaction   tr, prev_tr;
84    balance       saldo, prev_saldo;
85
86    for (ri = records.begin(); ri != records.end(); ri++)
87    {
88       tr = *ri;
89       std::cout << tr;
90
91       saldo += tr.mutation;
92       saldo = ~saldo;
93       std::cout << "    " << saldo;
94
95       if (ri != records.begin())
96       {
97          int  days_of_interest = tr.booked - prev_tr.booked;
98          amount  loaned_low,   loaned_high;
99          amount  interest_low, interest_high;
100
101          loaned_low = prev_saldo.debit();
102          if (loaned_low > 2500000)
103          {
104             loaned_high = loaned_low - 2500000;
105             loaned_low  = 2500000;
106          }
107          interest_low  = (loaned_low  * days_of_interest *  9 / 365 + 50) / 100;
108          interest_high = (loaned_high * days_of_interest * 12 / 365 + 50) / 100;
109
110          std::cout << std::setw(6) << std::right << days_of_interest;
111          std::cout << " " << interest_low << " " << interest_high << " " << interest_low + interest_high;
112       }
113       std::cout << "\n";
114       prev_tr = tr;
115       prev_saldo = saldo;
116    }
117 }
118
119 //----------------------------main----------------------------
120
121 static char  helptext[] = 
122      "Usage: loan [options] loanfile\n"
123      "\n"
124      "Options:\n"
125      "  -f <start>\n"
126      "  --from <start>   :  Calculate the report from <start> date\n"
127      "  -t <end>\n"
128      "  --to <end>       :  Calculate the report until <end> date\n"
129      "  --help           :  Print this helpful message\n"
130      "  -V\n"
131      "  --version        :  Print the version number\n";
132
133 static struct option long_options[] =
134 {
135    { "help",       no_argument,        0,   'h' },
136    { "from",       required_argument,  0,   'f' },
137    { "to",         required_argument,  0,   't' },
138    { "version",    no_argument,        0,   'V' },
139    { 0, 0, 0, 0 }
140 };
141
142 int main(int argc, char * argv[])
143 {
144
145    int      c;
146    int      option_index = 0;
147
148    String from_option, to_option;
149
150    while ((c = getopt_long(argc, argv, "hf:t:V", long_options, &option_index)) != -1)
151    {
152       switch (c)
153       {
154       case 'h':
155          std::cout << helptext;
156          exit(0);
157          break;
158
159       case 'V':
160          std::cout << "account version 1.4\n";
161          exit(0);
162          break;
163
164       case 'f':
165          from_option = String(optarg);
166          break;
167
168       case 't':
169          to_option = String(optarg);
170          break;
171       }
172    }
173
174    if (optind == argc)
175    {
176       std::cerr << "Usage: loan [options] loan_file\n";
177       exit(1);
178    }
179
180    loan loan_account;
181
182    loan_account.read(argv[optind]);
183    loan_account.report();
184
185    return 0;
186
187 }