Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2017-2020 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file exchangedb/exchangedb_transactions.c
18 : * @brief Logic to compute transaction totals of a transaction list for a coin
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include "taler_exchangedb_lib.h"
23 :
24 :
25 : enum GNUNET_GenericReturnValue
26 0 : TALER_EXCHANGEDB_calculate_transaction_list_totals (
27 : struct TALER_EXCHANGEDB_TransactionList *tl,
28 : const struct TALER_Amount *off,
29 : struct TALER_Amount *ret)
30 : {
31 0 : struct TALER_Amount spent = *off;
32 : struct TALER_Amount refunded;
33 : struct TALER_Amount deposit_fee;
34 : bool have_refund;
35 :
36 0 : GNUNET_assert (GNUNET_OK ==
37 : TALER_amount_set_zero (spent.currency,
38 : &refunded));
39 0 : have_refund = false;
40 0 : for (struct TALER_EXCHANGEDB_TransactionList *pos = tl;
41 0 : NULL != pos;
42 0 : pos = pos->next)
43 : {
44 0 : switch (pos->type)
45 : {
46 0 : case TALER_EXCHANGEDB_TT_DEPOSIT:
47 : /* spent += pos->amount_with_fee */
48 0 : if (0 >
49 0 : TALER_amount_add (&spent,
50 : &spent,
51 0 : &pos->details.deposit->amount_with_fee))
52 : {
53 0 : GNUNET_break (0);
54 0 : return GNUNET_SYSERR;
55 : }
56 0 : deposit_fee = pos->details.deposit->deposit_fee;
57 0 : break;
58 0 : case TALER_EXCHANGEDB_TT_MELT:
59 : /* spent += pos->amount_with_fee */
60 0 : if (0 >
61 0 : TALER_amount_add (&spent,
62 : &spent,
63 0 : &pos->details.melt->amount_with_fee))
64 : {
65 0 : GNUNET_break (0);
66 0 : return GNUNET_SYSERR;
67 : }
68 0 : break;
69 0 : case TALER_EXCHANGEDB_TT_REFUND:
70 : /* refunded += pos->refund_amount - pos->refund_fee */
71 0 : if (0 >
72 0 : TALER_amount_add (&refunded,
73 : &refunded,
74 0 : &pos->details.refund->refund_amount))
75 : {
76 0 : GNUNET_break (0);
77 0 : return GNUNET_SYSERR;
78 : }
79 0 : if (0 >
80 0 : TALER_amount_add (&spent,
81 : &spent,
82 0 : &pos->details.refund->refund_fee))
83 : {
84 0 : GNUNET_break (0);
85 0 : return GNUNET_SYSERR;
86 : }
87 0 : have_refund = true;
88 0 : break;
89 0 : case TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP:
90 : /* refunded += pos->value */
91 0 : if (0 >
92 0 : TALER_amount_add (&refunded,
93 : &refunded,
94 0 : &pos->details.old_coin_recoup->value))
95 : {
96 0 : GNUNET_break (0);
97 0 : return GNUNET_SYSERR;
98 : }
99 0 : break;
100 0 : case TALER_EXCHANGEDB_TT_RECOUP:
101 : /* spent += pos->value */
102 0 : if (0 >
103 0 : TALER_amount_add (&spent,
104 : &spent,
105 0 : &pos->details.recoup->value))
106 : {
107 0 : GNUNET_break (0);
108 0 : return GNUNET_SYSERR;
109 : }
110 0 : break;
111 0 : case TALER_EXCHANGEDB_TT_RECOUP_REFRESH:
112 : /* spent += pos->value */
113 0 : if (0 >
114 0 : TALER_amount_add (&spent,
115 : &spent,
116 0 : &pos->details.recoup_refresh->value))
117 : {
118 0 : GNUNET_break (0);
119 0 : return GNUNET_SYSERR;
120 : }
121 0 : break;
122 0 : case TALER_EXCHANGEDB_TT_PURSE_DEPOSIT:
123 : /* spent += pos->amount_with_fee */
124 0 : if (0 >
125 0 : TALER_amount_add (&spent,
126 : &spent,
127 0 : &pos->details.purse_deposit->amount))
128 : {
129 0 : GNUNET_break (0);
130 0 : return GNUNET_SYSERR;
131 : }
132 0 : deposit_fee = pos->details.purse_deposit->deposit_fee;
133 0 : break;
134 0 : case TALER_EXCHANGEDB_TT_PURSE_REFUND:
135 : /* refunded += pos->refund_amount - pos->refund_fee */
136 0 : if (0 >
137 0 : TALER_amount_add (&refunded,
138 : &refunded,
139 0 : &pos->details.purse_refund->refund_amount))
140 : {
141 0 : GNUNET_break (0);
142 0 : return GNUNET_SYSERR;
143 : }
144 0 : if (0 >
145 0 : TALER_amount_add (&spent,
146 : &spent,
147 0 : &pos->details.purse_refund->refund_fee))
148 : {
149 0 : GNUNET_break (0);
150 0 : return GNUNET_SYSERR;
151 : }
152 0 : have_refund = true;
153 0 : break;
154 0 : case TALER_EXCHANGEDB_TT_RESERVE_OPEN:
155 : /* spent += pos->amount_with_fee */
156 0 : if (0 >
157 0 : TALER_amount_add (&spent,
158 : &spent,
159 0 : &pos->details.reserve_open->coin_contribution))
160 : {
161 0 : GNUNET_break (0);
162 0 : return GNUNET_SYSERR;
163 : }
164 0 : break;
165 : }
166 : }
167 0 : if (have_refund)
168 : {
169 : /* If we gave any refund, also discount ONE deposit fee */
170 0 : if (0 >
171 0 : TALER_amount_add (&refunded,
172 : &refunded,
173 : &deposit_fee))
174 : {
175 0 : GNUNET_break (0);
176 0 : return GNUNET_SYSERR;
177 : }
178 : }
179 : /* spent = spent - refunded */
180 0 : if (0 >
181 0 : TALER_amount_subtract (&spent,
182 : &spent,
183 : &refunded))
184 : {
185 0 : GNUNET_break (0);
186 0 : return GNUNET_SYSERR;
187 : }
188 0 : *ret = spent;
189 0 : return GNUNET_OK;
190 : }
|