Line data Source code
1 : /*
2 : This file is part of TALER
3 : (C) 2019, 2020, 2021 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-products-ID.c
18 : * @brief implement GET /products/$ID
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include "taler-merchant-httpd_private-get-products-ID.h"
23 : #include <taler/taler_json_lib.h>
24 : #include "taler-merchant-httpd_helper.h"
25 : #include <taler/taler_util.h>
26 :
27 : /**
28 : * Handle a GET "/products/$ID" request.
29 : *
30 : * @param rh context of the handler
31 : * @param connection the MHD connection to handle
32 : * @param[in,out] hc context with further information about the request
33 : * @return MHD result code
34 : */
35 : MHD_RESULT
36 21 : TMH_private_get_products_ID (
37 : const struct TMH_RequestHandler *rh,
38 : struct MHD_Connection *connection,
39 : struct TMH_HandlerContext *hc)
40 : {
41 21 : struct TMH_MerchantInstance *mi = hc->instance;
42 21 : struct TALER_MERCHANTDB_ProductDetails pd = { 0 };
43 : enum GNUNET_DB_QueryStatus qs;
44 21 : size_t num_categories = 0;
45 21 : uint64_t *categories = NULL;
46 : json_t *jcategories;
47 :
48 21 : GNUNET_assert (NULL != mi);
49 21 : qs = TMH_db->lookup_product (TMH_db->cls,
50 21 : mi->settings.id,
51 21 : hc->infix,
52 : &pd,
53 : &num_categories,
54 : &categories);
55 21 : if (0 > qs)
56 : {
57 0 : GNUNET_break (0);
58 0 : return TALER_MHD_reply_with_error (connection,
59 : MHD_HTTP_INTERNAL_SERVER_ERROR,
60 : TALER_EC_GENERIC_DB_FETCH_FAILED,
61 : "lookup_product");
62 : }
63 21 : if (0 == qs)
64 : {
65 8 : return TALER_MHD_reply_with_error (connection,
66 : MHD_HTTP_NOT_FOUND,
67 : TALER_EC_MERCHANT_GENERIC_PRODUCT_UNKNOWN,
68 8 : hc->infix);
69 : }
70 13 : jcategories = json_array ();
71 13 : GNUNET_assert (NULL != jcategories);
72 13 : for (size_t i = 0; i<num_categories; i++)
73 : {
74 0 : GNUNET_assert (0 ==
75 : json_array_append_new (jcategories,
76 : json_integer (categories[i])));
77 : }
78 13 : GNUNET_free (categories);
79 :
80 : {
81 : MHD_RESULT ret;
82 : int64_t total_stock_api;
83 : char unit_total_stock_buf[64];
84 :
85 13 : if (INT64_MAX == pd.total_stock)
86 1 : total_stock_api = -1;
87 : else
88 12 : total_stock_api = (int64_t) pd.total_stock;
89 :
90 13 : TALER_MERCHANT_vk_format_fractional_string (
91 : TALER_MERCHANT_VK_STOCK,
92 : pd.total_stock,
93 : pd.total_stock_frac,
94 : sizeof (unit_total_stock_buf),
95 : unit_total_stock_buf);
96 :
97 13 : ret = TALER_MHD_REPLY_JSON_PACK (
98 : connection,
99 : MHD_HTTP_OK,
100 : GNUNET_JSON_pack_string ("product_name",
101 : pd.product_name),
102 : GNUNET_JSON_pack_string ("description",
103 : pd.description),
104 : GNUNET_JSON_pack_object_incref ("description_i18n",
105 : pd.description_i18n),
106 : GNUNET_JSON_pack_string ("unit",
107 : pd.unit),
108 : GNUNET_JSON_pack_array_steal ("categories",
109 : jcategories),
110 : // Note: deprecated field
111 : GNUNET_JSON_pack_allow_null (
112 : TALER_JSON_pack_amount ("price",
113 : (0 == pd.price_array_length)
114 : ? NULL
115 : : &pd.price_array[0])),
116 : TALER_JSON_pack_amount_array ("unit_price",
117 : pd.price_array_length,
118 : pd.price_array),
119 : GNUNET_JSON_pack_allow_null (
120 : GNUNET_JSON_pack_string ("image",
121 : pd.image)),
122 : GNUNET_JSON_pack_allow_null (
123 : GNUNET_JSON_pack_array_incref ("taxes",
124 : pd.taxes)),
125 : GNUNET_JSON_pack_int64 ("total_stock",
126 : total_stock_api),
127 : GNUNET_JSON_pack_string ("unit_total_stock",
128 : unit_total_stock_buf),
129 : GNUNET_JSON_pack_bool ("unit_allow_fraction",
130 : pd.allow_fractional_quantity),
131 : GNUNET_JSON_pack_uint64 ("unit_precision_level",
132 : pd.fractional_precision_level),
133 : TALER_JSON_pack_amount_array ("unit_price",
134 : pd.price_array_length,
135 : pd.price_array),
136 : GNUNET_JSON_pack_uint64 ("total_sold",
137 : pd.total_sold),
138 : GNUNET_JSON_pack_uint64 ("total_lost",
139 : pd.total_lost),
140 : GNUNET_JSON_pack_allow_null (
141 : GNUNET_JSON_pack_object_incref ("address",
142 : pd.address)),
143 : GNUNET_JSON_pack_allow_null (
144 : GNUNET_JSON_pack_timestamp ("next_restock",
145 : (pd.next_restock))),
146 : GNUNET_JSON_pack_uint64 ("product_group_id",
147 : pd.product_group_id),
148 : GNUNET_JSON_pack_uint64 ("money_pot_id",
149 : pd.money_pot_id),
150 : GNUNET_JSON_pack_bool ("price_is_net",
151 : pd.price_is_net),
152 : GNUNET_JSON_pack_uint64 ("minimum_age",
153 : pd.minimum_age));
154 13 : TALER_MERCHANTDB_product_details_free (&pd);
155 13 : return ret;
156 : }
157 : }
158 :
159 :
160 : /* end of taler-merchant-httpd_private-get-products-ID.c */
|