exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

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 }