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 : 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 : } 135 0 : } 136 0 : if (have_refund) 137 : { 138 : /* If we gave any refund, also discount ONE deposit fee */ 139 0 : if (0 > 140 0 : TALER_amount_add (&refunded, 141 : &refunded, 142 : &deposit_fee)) 143 : { 144 0 : GNUNET_break (0); 145 0 : return GNUNET_SYSERR; 146 : } 147 : } 148 : /* spent = spent - refunded */ 149 0 : if (0 > 150 0 : TALER_amount_subtract (&spent, 151 : &spent, 152 : &refunded)) 153 : { 154 0 : GNUNET_break (0); 155 0 : return GNUNET_SYSERR; 156 : } 157 0 : *ret = spent; 158 0 : return GNUNET_OK; 159 : }