merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

pg_mark_contract_paid.c (4908B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2022 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 backenddb/pg_mark_contract_paid.c
     18  * @brief Implementation of the mark_contract_paid function for Postgres
     19  * @author Iván Ávalos
     20  */
     21 #include "platform.h"
     22 #include <taler/taler_error_codes.h>
     23 #include <taler/taler_dbevents.h>
     24 #include <taler/taler_pq_lib.h>
     25 #include "pg_mark_contract_paid.h"
     26 #include "pg_helper.h"
     27 
     28 enum GNUNET_DB_QueryStatus
     29 TMH_PG_mark_contract_paid (
     30   void *cls,
     31   const char *instance_id,
     32   const struct TALER_PrivateContractHashP *h_contract_terms,
     33   const char *session_id,
     34   int16_t choice_index)
     35 {
     36   struct PostgresClosure *pg = cls;
     37   struct GNUNET_PQ_QueryParam params[] = {
     38     GNUNET_PQ_query_param_string (instance_id),
     39     GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
     40     GNUNET_PQ_query_param_string (session_id),
     41     (choice_index >= 0)
     42       ? GNUNET_PQ_query_param_int16 (&choice_index)
     43       : GNUNET_PQ_query_param_null (),
     44     GNUNET_PQ_query_param_end
     45   };
     46   struct GNUNET_PQ_QueryParam uparams[] = {
     47     GNUNET_PQ_query_param_string (instance_id),
     48     GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
     49     GNUNET_PQ_query_param_end
     50   };
     51   enum GNUNET_DB_QueryStatus qs;
     52 
     53   /* Session ID must always be given by the caller. */
     54   GNUNET_assert (NULL != session_id);
     55 
     56   /* no preflight check here, run in transaction by caller! */
     57   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     58               "Marking h_contract_terms '%s' of %s as paid for session `%s'\n",
     59               GNUNET_h2s (&h_contract_terms->hash),
     60               instance_id,
     61               session_id);
     62   PREPARE (pg,
     63            "mark_contract_paid",
     64            "UPDATE merchant_contract_terms SET"
     65            " paid=TRUE"
     66            ",session_id=$3"
     67            ",choice_index=$4"
     68            " WHERE h_contract_terms=$2"
     69            "   AND merchant_serial="
     70            "     (SELECT merchant_serial"
     71            "        FROM merchant_instances"
     72            "       WHERE merchant_id=$1)");
     73   qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
     74                                            "mark_contract_paid",
     75                                            params);
     76   if (qs <= 0)
     77     return qs;
     78   PREPARE (pg,
     79            "mark_inventory_sold",
     80            "UPDATE merchant_inventory SET"
     81            " total_sold = total_sold"
     82            "   + order_locks.total_locked"
     83            "   + ((merchant_inventory.total_sold_frac::BIGINT"
     84            "       + order_locks.total_locked_frac::BIGINT) / 1000000)"
     85            " ,total_sold_frac ="
     86            "    ((merchant_inventory.total_sold_frac::BIGINT"
     87            "      + order_locks.total_locked_frac::BIGINT) % 1000000)::INT4"
     88            " FROM (SELECT total_locked,total_locked_frac,product_serial"
     89            "       FROM merchant_order_locks"
     90            "       WHERE order_serial="
     91            "       (SELECT order_serial"
     92            "          FROM merchant_contract_terms"
     93            "         WHERE h_contract_terms=$2"
     94            "           AND merchant_serial="
     95            "           (SELECT merchant_serial"
     96            "              FROM merchant_instances"
     97            "             WHERE merchant_id=$1))"
     98            "       ) AS order_locks"
     99            " WHERE merchant_inventory.product_serial"
    100            "             =order_locks.product_serial");
    101   qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
    102                                            "mark_inventory_sold",
    103                                            uparams);
    104   if (qs < 0)
    105     return qs; /* 0: no inventory management, that's OK! */
    106   /* ON DELETE CASCADE deletes from merchant_order_locks */
    107   PREPARE (pg,
    108            "delete_completed_order",
    109            "WITH md AS"
    110            "  (SELECT merchant_serial"
    111            "     FROM merchant_instances"
    112            "    WHERE merchant_id=$1) "
    113            "DELETE"
    114            " FROM merchant_orders"
    115            " WHERE order_serial="
    116            "       (SELECT order_serial"
    117            "          FROM merchant_contract_terms"
    118            "          JOIN md USING (merchant_serial)"
    119            "         WHERE h_contract_terms=$2)");
    120   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    121                                              "delete_completed_order",
    122                                              uparams);
    123 }