taler-merchant-httpd_get-private-pos.c (7636B)
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_get-private-pos.c 18 * @brief implement GET /private/pos 19 * @author Christian Grothoff 20 */ 21 #include "taler/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 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 TALER_MERCHANT_vk_format_fractional_string ( 123 TALER_MERCHANT_VK_STOCK, 124 pd->total_stock, 125 pd->total_stock_frac, 126 sizeof (unit_total_stock_buf), 127 unit_total_stock_buf); 128 129 GNUNET_assert ( 130 0 == 131 json_array_append_new ( 132 pa, 133 GNUNET_JSON_PACK ( 134 GNUNET_JSON_pack_string ("product_name", 135 pd->product_name), 136 GNUNET_JSON_pack_string ("description", 137 pd->description), 138 GNUNET_JSON_pack_object_incref ("description_i18n", 139 (json_t *) pd->description_i18n), 140 GNUNET_JSON_pack_string ("unit", 141 pd->unit), 142 // Note: deprecated field 143 GNUNET_JSON_pack_allow_null ( 144 TALER_JSON_pack_amount ("price", 145 (0 == pd->price_array_length) 146 ? NULL 147 : &pd->price_array[0])), 148 TALER_JSON_pack_amount_array ("unit_price", 149 pd->price_array_length, 150 pd->price_array), 151 GNUNET_JSON_pack_allow_null ( 152 GNUNET_JSON_pack_string ("image", 153 pd->image)), 154 GNUNET_JSON_pack_array_steal ("categories", 155 cata), 156 GNUNET_JSON_pack_allow_null ( 157 GNUNET_JSON_pack_array_incref ("taxes", 158 (json_t *) pd->taxes)), 159 GNUNET_JSON_pack_int64 ("total_stock", 160 total_stock_api), 161 GNUNET_JSON_pack_string ("unit_total_stock", 162 unit_total_stock_buf), 163 GNUNET_JSON_pack_bool ("unit_allow_fraction", 164 pd->allow_fractional_quantity), 165 GNUNET_JSON_pack_uint64 ("unit_precision_level", 166 pd->fractional_precision_level), 167 GNUNET_JSON_pack_uint64 ("minimum_age", 168 pd->minimum_age), 169 GNUNET_JSON_pack_uint64 ("product_serial", 170 product_serial), 171 GNUNET_JSON_pack_string ("product_id", 172 product_id)))); 173 } 174 175 176 MHD_RESULT 177 TMH_private_get_pos (const struct TMH_RequestHandler *rh, 178 struct MHD_Connection *connection, 179 struct TMH_HandlerContext *hc) 180 { 181 struct Context ctx; 182 enum GNUNET_DB_QueryStatus qs; 183 184 ctx.pa = json_array (); 185 GNUNET_assert (NULL != ctx.pa); 186 ctx.ca = json_array (); 187 GNUNET_assert (NULL != ctx.ca); 188 GNUNET_assert ( 189 0 == json_array_append_new ( 190 ctx.ca, 191 GNUNET_JSON_PACK ( 192 GNUNET_JSON_pack_uint64 ("id", 193 0), 194 GNUNET_JSON_pack_string ("name", 195 "default")))); 196 qs = TMH_db->lookup_categories (TMH_db->cls, 197 hc->instance->settings.id, 198 &add_category, 199 &ctx); 200 if (0 > qs) 201 { 202 GNUNET_break (0); 203 json_decref (ctx.pa); 204 json_decref (ctx.ca); 205 return TALER_MHD_reply_with_error (connection, 206 MHD_HTTP_INTERNAL_SERVER_ERROR, 207 TALER_EC_GENERIC_DB_FETCH_FAILED, 208 NULL); 209 } 210 qs = TMH_db->lookup_all_products (TMH_db->cls, 211 hc->instance->settings.id, 212 &add_product, 213 &ctx); 214 if (0 > qs) 215 { 216 GNUNET_break (0); 217 json_decref (ctx.pa); 218 json_decref (ctx.ca); 219 return TALER_MHD_reply_with_error (connection, 220 MHD_HTTP_INTERNAL_SERVER_ERROR, 221 TALER_EC_GENERIC_DB_FETCH_FAILED, 222 NULL); 223 } 224 return TALER_MHD_REPLY_JSON_PACK ( 225 connection, 226 MHD_HTTP_OK, 227 GNUNET_JSON_pack_array_steal ("categories", 228 ctx.ca), 229 GNUNET_JSON_pack_array_steal ("products", 230 ctx.pa)); 231 } 232 233 234 /* end of taler-merchant-httpd_get-private-pos.c */