summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c33
-rw-r--r--src/lib/merchant_api_post_orders.c4
-rw-r--r--src/testing/test_merchant_api.c31
3 files changed, 68 insertions, 0 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c
index 7fff7226..c97ac21c 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -177,6 +177,9 @@ struct InventoryProduct
};
+#define PRODUCT_OOS_OFFSET -3
+
+
/**
* Execute the database transaction to setup the order.
*
@@ -249,6 +252,8 @@ execute_transaction (struct TMH_HandlerContext *hc,
{
/* qs == 0: lock acquisition failed due to insufficient stocks */
TMH_db->rollback (TMH_db->cls);
+ if (0 == qs)
+ qs = PRODUCT_OOS_OFFSET - i; /* indicate which product is causing the issue */
return qs;
}
}
@@ -435,6 +440,34 @@ execute_order (struct MHD_Connection *connection,
"serialization error, maybe try again?");
}
+ /* If we have a product that has insufficient quantities,
+ generate the details for the response. */
+ if (PRODUCT_OOS_OFFSET >= qs)
+ {
+ unsigned int i = -qs + PRODUCT_OOS_OFFSET;
+ struct TALER_MERCHANTDB_ProductDetails pd;
+
+ qs = TMH_db->lookup_product (TMH_db->cls,
+ hc->instance->settings.id,
+ inventory_products[i].product_id,
+ &pd);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_GONE,
+ "{s:s,s:I,s:I,s:o?}",
+ "product_id",
+ inventory_products[i].product_id,
+ "requested_quantity",
+ inventory_products[i].quantity,
+ "available_quantity",
+ pd.total_stock - pd.total_sold
+ - pd.total_lost,
+ "restock_expected",
+ (pd.next_restock.abs_value_us == 0) ?
+ NULL :
+ GNUNET_JSON_from_time_abs (
+ pd.next_restock));
+ }
+
{
/* Hard error could be constraint violation,
check if order already exists */
diff --git a/src/lib/merchant_api_post_orders.c b/src/lib/merchant_api_post_orders.c
index 73815fdf..f4cc5290 100644
--- a/src/lib/merchant_api_post_orders.c
+++ b/src/lib/merchant_api_post_orders.c
@@ -146,6 +146,10 @@ handle_post_order_finished (void *cls,
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
break;
+ case MHD_HTTP_GONE:
+ /* The quantity of some product requested was not available. */
+ // FIXME: parse the OutOfStockResponse.
+ break;
default:
/* unexpected response code */
hr.ec = TALER_JSON_get_error_code (json);
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index 33de86ed..9fee2e3e 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -310,6 +310,21 @@ run (void *cls,
"a product",
"EUR:1",
MHD_HTTP_NO_CONTENT),
+ TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3",
+ merchant_url,
+ "product-3",
+ "a product",
+ json_object (),
+ "can",
+ "EUR:1",
+ json_object (),
+ json_object (),
+ 5,
+ 0,
+ json_object (),
+ GNUNET_TIME_relative_to_absolute (
+ GNUNET_TIME_UNIT_MINUTES),
+ MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_lock_product ("lock-product-p3",
merchant_url,
"product-3",
@@ -346,6 +361,22 @@ run (void *cls,
"x-taler-bank",
"unknown-product/2",
""),
+ TALER_TESTING_cmd_merchant_post_orders2 (
+ "create-proposal-p3-not-enough-stock",
+ merchant_url,
+ MHD_HTTP_GONE,
+ "{\"max_fee\":\"EUR:0.5\",\
+ \"order_id\":\"order-p3\",\
+ \"refund_deadline\": {\"t_ms\": 0},\
+ \"pay_deadline\": {\"t_ms\": \"never\" },\
+ \"amount\":\"EUR:5.0\",\
+ \"summary\": \"merchant-lib testcase\",\
+ \"fulfillment_url\": \"https://example.com/\",\
+ \"products\": [ {\"description\":\"ice cream\",\
+ \"value\":\"{EUR:5}\"} ] }",
+ "x-taler-bank",
+ "product-3/24",
+ ""),
TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3",
merchant_url,
MHD_HTTP_OK,