LCOV - code coverage report
Current view: top level - backend - taler-merchant-httpd_private-post-products-ID-lock.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.4 % 72 50
Test Date: 2025-11-28 21:09:21 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   (C) 2020, 2021 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify
       6              :   it under the terms of the GNU Affero General Public License as
       7              :   published by the Free Software Foundation; either version 3,
       8              :   or (at your option) any later version.
       9              : 
      10              :   TALER is distributed in the hope that it will be useful, but
      11              :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13              :   GNU General Public License for more details.
      14              : 
      15              :   You should have received a copy of the GNU General Public
      16              :   License along with TALER; see the file COPYING.  If not,
      17              :   see <http://www.gnu.org/licenses/>
      18              : */
      19              : 
      20              : /**
      21              :  * @file taler-merchant-httpd_private-post-products-ID-lock.c
      22              :  * @brief implementing POST /products/$ID/lock request handling
      23              :  * @author Christian Grothoff
      24              :  */
      25              : #include "platform.h"
      26              : #include "taler-merchant-httpd_private-post-products-ID-lock.h"
      27              : #include "taler-merchant-httpd_helper.h"
      28              : #include <taler/taler_json_lib.h>
      29              : 
      30              : 
      31              : MHD_RESULT
      32           14 : TMH_private_post_products_ID_lock (
      33              :   const struct TMH_RequestHandler *rh,
      34              :   struct MHD_Connection *connection,
      35              :   struct TMH_HandlerContext *hc)
      36              : {
      37           14 :   struct TMH_MerchantInstance *mi = hc->instance;
      38           14 :   const char *product_id = hc->infix;
      39              :   enum GNUNET_DB_QueryStatus qs;
      40              :   const char *uuids;
      41              :   struct GNUNET_Uuid uuid;
      42              :   uint64_t quantity;
      43              :   bool quantity_missing;
      44           14 :   const char *unit_quantity = NULL;
      45           14 :   bool unit_quantity_missing = true;
      46              :   struct GNUNET_TIME_Relative duration;
      47              :   struct GNUNET_JSON_Specification spec[] = {
      48           14 :     GNUNET_JSON_spec_string ("lock_uuid",
      49              :                              &uuids),
      50           14 :     GNUNET_JSON_spec_relative_time ("duration",
      51              :                                     &duration),
      52           14 :     GNUNET_JSON_spec_mark_optional (
      53              :       GNUNET_JSON_spec_uint64 ("quantity",
      54              :                                &quantity),
      55              :       &quantity_missing),
      56           14 :     GNUNET_JSON_spec_mark_optional (
      57              :       GNUNET_JSON_spec_string ("unit_quantity",
      58              :                                &unit_quantity),
      59              :       &unit_quantity_missing),
      60           14 :     GNUNET_JSON_spec_end ()
      61              :   };
      62              : 
      63           14 :   GNUNET_assert (NULL != mi);
      64           14 :   GNUNET_assert (NULL != product_id);
      65              :   {
      66              :     enum GNUNET_GenericReturnValue res;
      67              : 
      68           14 :     res = TALER_MHD_parse_json_data (connection,
      69           14 :                                      hc->request_body,
      70              :                                      spec);
      71           14 :     if (GNUNET_OK != res)
      72              :       return (GNUNET_NO == res)
      73              :              ? MHD_YES
      74            0 :              : MHD_NO;
      75              :   }
      76           14 :   TMH_uuid_from_string (uuids,
      77              :                         &uuid);
      78           14 :   TMH_db->expire_locks (TMH_db->cls);
      79              :   {
      80           14 :     struct TALER_MERCHANTDB_ProductDetails pd = { 0 };
      81              :     size_t num_categories;
      82              :     uint64_t *categories;
      83           14 :     uint64_t normalized_quantity = 0;
      84           14 :     uint32_t normalized_quantity_frac = 0;
      85              : 
      86           14 :     if (quantity_missing && unit_quantity_missing)
      87              :     {
      88            0 :       quantity = 1;
      89            0 :       quantity_missing = false;
      90              :     }
      91           14 :     else if ( (! quantity_missing) &&
      92            0 :               (quantity > (uint64_t) INT64_MAX) )
      93              :     {
      94            0 :       GNUNET_break_op (0);
      95            4 :       return TALER_MHD_reply_with_error (connection,
      96              :                                          MHD_HTTP_BAD_REQUEST,
      97              :                                          TALER_EC_GENERIC_PARAMETER_MALFORMED,
      98              :                                          "quantity");
      99              :     }
     100              : 
     101           14 :     qs = TMH_db->lookup_product (TMH_db->cls,
     102           14 :                                  mi->settings.id,
     103              :                                  product_id,
     104              :                                  &pd,
     105              :                                  &num_categories,
     106              :                                  &categories);
     107           14 :     switch (qs)
     108              :     {
     109            0 :     case GNUNET_DB_STATUS_HARD_ERROR:
     110            0 :       GNUNET_break (0);
     111            0 :       TALER_MERCHANTDB_product_details_free (&pd);
     112            0 :       GNUNET_free (categories);
     113            0 :       return TALER_MHD_reply_with_error (
     114              :         connection,
     115              :         MHD_HTTP_INTERNAL_SERVER_ERROR,
     116              :         TALER_EC_GENERIC_DB_FETCH_FAILED,
     117              :         "lookup_product");
     118            0 :     case GNUNET_DB_STATUS_SOFT_ERROR:
     119            0 :       GNUNET_break (0);
     120            0 :       TALER_MERCHANTDB_product_details_free (&pd);
     121            0 :       GNUNET_free (categories);
     122            0 :       return TALER_MHD_reply_with_error (
     123              :         connection,
     124              :         MHD_HTTP_INTERNAL_SERVER_ERROR,
     125              :         TALER_EC_GENERIC_DB_SOFT_FAILURE,
     126              :         "lookup_product");
     127            2 :     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     128            2 :       GNUNET_break_op (0);
     129            2 :       TALER_MERCHANTDB_product_details_free (&pd);
     130            2 :       GNUNET_free (categories);
     131            2 :       return TALER_MHD_reply_with_error (
     132              :         connection,
     133              :         MHD_HTTP_NOT_FOUND,
     134              :         TALER_EC_MERCHANT_GENERIC_PRODUCT_UNKNOWN,
     135              :         product_id);
     136           12 :     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     137           12 :       break;
     138              :     }
     139           12 :     GNUNET_free (categories);
     140              :     {
     141              :       const char *eparam;
     142           12 :       if (GNUNET_OK !=
     143           12 :           TMH_process_quantity_inputs (TMH_VK_QUANTITY,
     144           12 :                                        pd.allow_fractional_quantity,
     145              :                                        quantity_missing,
     146              :                                        (int64_t) quantity,
     147              :                                        unit_quantity_missing,
     148              :                                        unit_quantity,
     149              :                                        &normalized_quantity,
     150              :                                        &normalized_quantity_frac,
     151              :                                        &eparam))
     152              :       {
     153            2 :         TALER_MERCHANTDB_product_details_free (&pd);
     154            2 :         GNUNET_break_op (0);
     155            2 :         return TALER_MHD_reply_with_error (connection,
     156              :                                            MHD_HTTP_BAD_REQUEST,
     157              :                                            TALER_EC_GENERIC_PARAMETER_MALFORMED,
     158              :                                            eparam);
     159              :       }
     160              :     }
     161           10 :     quantity = normalized_quantity;
     162           10 :     qs = TMH_db->lock_product (TMH_db->cls,
     163           10 :                                mi->settings.id,
     164              :                                product_id,
     165              :                                &uuid,
     166              :                                quantity,
     167              :                                normalized_quantity_frac,
     168              :                                GNUNET_TIME_relative_to_timestamp (duration));
     169           10 :     TALER_MERCHANTDB_product_details_free (&pd);
     170              :   }
     171           10 :   switch (qs)
     172              :   {
     173            0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     174            0 :     GNUNET_break (0);
     175            0 :     return TALER_MHD_reply_with_error (
     176              :       connection,
     177              :       MHD_HTTP_INTERNAL_SERVER_ERROR,
     178              :       TALER_EC_GENERIC_DB_STORE_FAILED,
     179              :       NULL);
     180            0 :   case GNUNET_DB_STATUS_SOFT_ERROR:
     181            0 :     GNUNET_break (0);
     182            0 :     return TALER_MHD_reply_with_error (
     183              :       connection,
     184              :       MHD_HTTP_INTERNAL_SERVER_ERROR,
     185              :       TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
     186              :       "Serialization error for single-statment request");
     187            3 :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     188            3 :     GNUNET_break_op (0);
     189            3 :     return TALER_MHD_reply_with_error (
     190              :       connection,
     191              :       MHD_HTTP_GONE,
     192              :       TALER_EC_MERCHANT_PRIVATE_POST_PRODUCTS_LOCK_INSUFFICIENT_STOCKS,
     193              :       product_id);
     194            7 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     195            7 :     return TALER_MHD_reply_static (connection,
     196              :                                    MHD_HTTP_NO_CONTENT,
     197              :                                    NULL,
     198              :                                    NULL,
     199              :                                    0);
     200              :   }
     201            0 :   GNUNET_assert (0);
     202              :   return MHD_NO;
     203              : }
     204              : 
     205              : 
     206              : /* end of taler-merchant-httpd_private-patch-products-ID-lock.c */
        

Generated by: LCOV version 2.0-1