exchangedb_transactions.c (5620B)
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 "taler/platform.h" 22 #include "taler/taler_exchangedb_lib.h" 23 24 25 enum GNUNET_GenericReturnValue 26 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 struct TALER_Amount spent = *off; 32 struct TALER_Amount refunded; 33 struct TALER_Amount deposit_fee; 34 bool have_refund; 35 36 GNUNET_assert (GNUNET_OK == 37 TALER_amount_set_zero (spent.currency, 38 &refunded)); 39 have_refund = false; 40 for (struct TALER_EXCHANGEDB_TransactionList *pos = tl; 41 NULL != pos; 42 pos = pos->next) 43 { 44 switch (pos->type) 45 { 46 case TALER_EXCHANGEDB_TT_DEPOSIT: 47 /* spent += pos->amount_with_fee */ 48 if (0 > 49 TALER_amount_add (&spent, 50 &spent, 51 &pos->details.deposit->amount_with_fee)) 52 { 53 GNUNET_break (0); 54 return GNUNET_SYSERR; 55 } 56 deposit_fee = pos->details.deposit->deposit_fee; 57 break; 58 case TALER_EXCHANGEDB_TT_MELT: 59 /* spent += pos->amount_with_fee */ 60 if (0 > 61 TALER_amount_add (&spent, 62 &spent, 63 &pos->details.melt->amount_with_fee)) 64 { 65 GNUNET_break (0); 66 return GNUNET_SYSERR; 67 } 68 break; 69 case TALER_EXCHANGEDB_TT_REFUND: 70 /* refunded += pos->refund_amount - pos->refund_fee */ 71 if (0 > 72 TALER_amount_add (&refunded, 73 &refunded, 74 &pos->details.refund->refund_amount)) 75 { 76 GNUNET_break (0); 77 return GNUNET_SYSERR; 78 } 79 if (0 > 80 TALER_amount_add (&spent, 81 &spent, 82 &pos->details.refund->refund_fee)) 83 { 84 GNUNET_break (0); 85 return GNUNET_SYSERR; 86 } 87 have_refund = true; 88 break; 89 case TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP: 90 /* refunded += pos->value */ 91 if (0 > 92 TALER_amount_add (&refunded, 93 &refunded, 94 &pos->details.old_coin_recoup->value)) 95 { 96 GNUNET_break (0); 97 return GNUNET_SYSERR; 98 } 99 break; 100 case TALER_EXCHANGEDB_TT_RECOUP: 101 /* spent += pos->value */ 102 if (0 > 103 TALER_amount_add (&spent, 104 &spent, 105 &pos->details.recoup->value)) 106 { 107 GNUNET_break (0); 108 return GNUNET_SYSERR; 109 } 110 break; 111 case TALER_EXCHANGEDB_TT_RECOUP_REFRESH: 112 /* spent += pos->value */ 113 if (0 > 114 TALER_amount_add (&spent, 115 &spent, 116 &pos->details.recoup_refresh->value)) 117 { 118 GNUNET_break (0); 119 return GNUNET_SYSERR; 120 } 121 break; 122 case TALER_EXCHANGEDB_TT_PURSE_DEPOSIT: 123 /* spent += pos->amount_with_fee */ 124 if (0 > 125 TALER_amount_add (&spent, 126 &spent, 127 &pos->details.purse_deposit->amount)) 128 { 129 GNUNET_break (0); 130 return GNUNET_SYSERR; 131 } 132 deposit_fee = pos->details.purse_deposit->deposit_fee; 133 break; 134 case TALER_EXCHANGEDB_TT_PURSE_REFUND: 135 /* refunded += pos->refund_amount - pos->refund_fee */ 136 if (0 > 137 TALER_amount_add (&refunded, 138 &refunded, 139 &pos->details.purse_refund->refund_amount)) 140 { 141 GNUNET_break (0); 142 return GNUNET_SYSERR; 143 } 144 if (0 > 145 TALER_amount_add (&spent, 146 &spent, 147 &pos->details.purse_refund->refund_fee)) 148 { 149 GNUNET_break (0); 150 return GNUNET_SYSERR; 151 } 152 have_refund = true; 153 break; 154 case TALER_EXCHANGEDB_TT_RESERVE_OPEN: 155 /* spent += pos->amount_with_fee */ 156 if (0 > 157 TALER_amount_add (&spent, 158 &spent, 159 &pos->details.reserve_open->coin_contribution)) 160 { 161 GNUNET_break (0); 162 return GNUNET_SYSERR; 163 } 164 break; 165 } 166 } 167 if (have_refund) 168 { 169 /* If we gave any refund, also discount ONE deposit fee */ 170 if (0 > 171 TALER_amount_add (&refunded, 172 &refunded, 173 &deposit_fee)) 174 { 175 GNUNET_break (0); 176 return GNUNET_SYSERR; 177 } 178 } 179 /* spent = spent - refunded */ 180 if (0 > 181 TALER_amount_subtract (&spent, 182 &spent, 183 &refunded)) 184 { 185 GNUNET_break (0); 186 return GNUNET_SYSERR; 187 } 188 *ret = spent; 189 return GNUNET_OK; 190 }