merchant

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

taler-merchant-httpd_private-get-pos.c (7519B)


      1 /*
      2   This file is part of TALER
      3   (C) 2019, 2020, 2021, 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero 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 taler-merchant-httpd_private-get-pos.c
     18  * @brief implement GET /private/pos
     19  * @author Christian Grothoff
     20  */
     21 #include "platform.h"
     22 #include "taler-merchant-httpd_private-get-pos.h"
     23 #include <taler/taler_json_lib.h>
     24 #include "taler-merchant-httpd_helper.h"
     25 
     26 /**
     27  * Closure for add_product().
     28  */
     29 struct Context
     30 {
     31   /**
     32    * JSON array of products we are building.
     33    */
     34   json_t *pa;
     35 
     36   /**
     37    * JSON array of categories we are building.
     38    */
     39   json_t *ca;
     40 
     41 };
     42 
     43 
     44 /**
     45  * Add category to the @e ca array.
     46  *
     47  * @param cls a `struct Context` with JSON arrays to build
     48  * @param category_id ID of the category
     49  * @param category_name name of the category
     50  * @param category_name_i18n translations of the @a category_name
     51  * @param product_count number of products in the category
     52  */
     53 static void
     54 add_category (
     55   void *cls,
     56   uint64_t category_id,
     57   const char *category_name,
     58   const json_t *category_name_i18n,
     59   uint64_t product_count)
     60 {
     61   struct Context *ctx = cls;
     62 
     63   (void) product_count;
     64   GNUNET_assert (
     65     0 ==
     66     json_array_append_new (
     67       ctx->ca,
     68       GNUNET_JSON_PACK (
     69         GNUNET_JSON_pack_uint64 ("id",
     70                                  category_id),
     71         GNUNET_JSON_pack_object_incref ("name_i18n",
     72                                         (json_t *) category_name_i18n),
     73         GNUNET_JSON_pack_string ("name",
     74                                  category_name))));
     75 }
     76 
     77 
     78 /**
     79  * Add product details to our JSON array.
     80  *
     81  * @param cls a `struct Context` with JSON arrays to build
     82  * @param product_serial row ID of the product
     83  * @param product_id ID of the product
     84  * @param pd full product details
     85  * @param num_categories length of @a categories array
     86  * @param categories array of categories the
     87  *   product is in
     88  */
     89 static void
     90 add_product (void *cls,
     91              uint64_t product_serial,
     92              const char *product_id,
     93              const struct TALER_MERCHANTDB_ProductDetails *pd,
     94              size_t num_categories,
     95              const uint64_t *categories)
     96 {
     97   struct Context *ctx = cls;
     98   json_t *pa = ctx->pa;
     99   json_t *cata;
    100   int64_t total_stock_api;
    101   char unit_total_stock_buf[64];
    102 
    103   cata = json_array ();
    104   GNUNET_assert (NULL != cata);
    105   for (size_t i = 0; i<num_categories; i++)
    106     GNUNET_assert (
    107       0 == json_array_append_new (
    108         cata,
    109         json_integer (categories[i])));
    110   if (0 == num_categories)
    111   {
    112     // If there is no category, we return the default category
    113     GNUNET_assert (
    114       0 == json_array_append_new (
    115         cata,
    116         json_integer (0)));
    117   }
    118   if (INT64_MAX == pd->total_stock)
    119     total_stock_api = -1;
    120   else
    121     total_stock_api = (int64_t) pd->total_stock;
    122   TMH_format_fractional_string (TMH_VK_STOCK,
    123                                 pd->total_stock,
    124                                 pd->total_stock_frac,
    125                                 sizeof (unit_total_stock_buf),
    126                                 unit_total_stock_buf);
    127 
    128   GNUNET_assert (
    129     0 ==
    130     json_array_append_new (
    131       pa,
    132       GNUNET_JSON_PACK (
    133         GNUNET_JSON_pack_string ("product_name",
    134                                  pd->product_name),
    135         GNUNET_JSON_pack_string ("description",
    136                                  pd->description),
    137         GNUNET_JSON_pack_object_incref ("description_i18n",
    138                                         (json_t *) pd->description_i18n),
    139         GNUNET_JSON_pack_string ("unit",
    140                                  pd->unit),
    141         TALER_JSON_pack_amount ("price",
    142                                 &pd->price),
    143         TALER_JSON_pack_amount_array ("unit_price",
    144                                       pd->price_array_length,
    145                                       pd->price_array),
    146         GNUNET_JSON_pack_allow_null (
    147           GNUNET_JSON_pack_string ("image",
    148                                    pd->image)),
    149         GNUNET_JSON_pack_array_steal ("categories",
    150                                       cata),
    151         GNUNET_JSON_pack_allow_null (
    152           GNUNET_JSON_pack_array_incref ("taxes",
    153                                          (json_t *) pd->taxes)),
    154         GNUNET_JSON_pack_int64 ("total_stock",
    155                                 total_stock_api),
    156         GNUNET_JSON_pack_string ("unit_total_stock",
    157                                  unit_total_stock_buf),
    158         GNUNET_JSON_pack_bool ("unit_allow_fraction",
    159                                pd->allow_fractional_quantity),
    160         GNUNET_JSON_pack_uint64 ("unit_precision_level",
    161                                  pd->fractional_precision_level),
    162         GNUNET_JSON_pack_uint64 ("minimum_age",
    163                                  pd->minimum_age),
    164         GNUNET_JSON_pack_uint64 ("product_serial",
    165                                  product_serial),
    166         GNUNET_JSON_pack_string ("product_id",
    167                                  product_id))));
    168 }
    169 
    170 
    171 MHD_RESULT
    172 TMH_private_get_pos (const struct TMH_RequestHandler *rh,
    173                      struct MHD_Connection *connection,
    174                      struct TMH_HandlerContext *hc)
    175 {
    176   struct Context ctx;
    177   enum GNUNET_DB_QueryStatus qs;
    178 
    179   ctx.pa = json_array ();
    180   GNUNET_assert (NULL != ctx.pa);
    181   ctx.ca = json_array ();
    182   GNUNET_assert (NULL != ctx.ca);
    183   GNUNET_assert (
    184     0 == json_array_append_new (
    185       ctx.ca,
    186       GNUNET_JSON_PACK (
    187         GNUNET_JSON_pack_uint64 ("id",
    188                                  0),
    189         GNUNET_JSON_pack_string ("name",
    190                                  "default"))));
    191   qs = TMH_db->lookup_categories (TMH_db->cls,
    192                                   hc->instance->settings.id,
    193                                   &add_category,
    194                                   &ctx);
    195   if (0 > qs)
    196   {
    197     GNUNET_break (0);
    198     json_decref (ctx.pa);
    199     json_decref (ctx.ca);
    200     return TALER_MHD_reply_with_error (connection,
    201                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
    202                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
    203                                        NULL);
    204   }
    205   qs = TMH_db->lookup_all_products (TMH_db->cls,
    206                                     hc->instance->settings.id,
    207                                     &add_product,
    208                                     &ctx);
    209   if (0 > qs)
    210   {
    211     GNUNET_break (0);
    212     json_decref (ctx.pa);
    213     json_decref (ctx.ca);
    214     return TALER_MHD_reply_with_error (connection,
    215                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
    216                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
    217                                        NULL);
    218   }
    219   return TALER_MHD_REPLY_JSON_PACK (
    220     connection,
    221     MHD_HTTP_OK,
    222     GNUNET_JSON_pack_array_steal ("categories",
    223                                   ctx.ca),
    224     GNUNET_JSON_pack_array_steal ("products",
    225                                   ctx.pa));
    226 }
    227 
    228 
    229 /* end of taler-merchant-httpd_private-get-pos.c */