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