commit a22d66a2a8614efca9f505cd0097e162febce670
parent 11d0700360eb768d4cf502eea6be4c253702570d
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 16 Mar 2026 22:12:18 +0100
fix #11253
Diffstat:
1 file changed, 115 insertions(+), 99 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_get-private-orders.c b/src/backend/taler-merchant-httpd_get-private-orders.c
@@ -33,7 +33,7 @@
#define MAX_DELTA 1024
#define CSV_HEADER \
- "Order ID,Row,Timestamp,Amount,Refund amount,Pending refund amount,Summary,Refundable,Paid\r\n"
+ "Order ID,Row,YYYY-MM-DD,HH:MM,Timestamp,Amount,Refund amount,Pending refund amount,Summary,Refundable,Paid\r\n"
#define CSV_FOOTER "\r\n"
#define XML_HEADER "<?xml version=\"1.0\"?>" \
@@ -108,30 +108,19 @@ struct TMH_PendingOrder
* Running total of order amounts, for totals row in CSV/XML/PDF.
* Initialised to zero on first order seen.
*/
- struct TALER_Amount total_amount;
+ struct TALER_AmountSet total_amount;
/**
* Running total of granted refund amounts.
* Initialised to zero on first paid order seen.
*/
- struct TALER_Amount total_refund_amount;
+ struct TALER_AmountSet total_refund_amount;
/**
* Running total of pending refund amounts.
* Initialised to zero on first paid order seen.
*/
- struct TALER_Amount total_pending_refund_amount;
-
- /**
- * True once @e total_amount has been initialised with a currency.
- */
- bool total_amount_initialized;
-
- /**
- * True once @e total_refund_amount / @e total_pending_refund_amount
- * have been initialised with a currency.
- */
- bool total_refund_initialized;
+ struct TALER_AmountSet total_pending_refund_amount;
/**
* The name of the instance we are querying for.
@@ -294,6 +283,9 @@ cleanup (void *ctx)
po->order_timeout_task = NULL;
}
json_decref (po->pa);
+ TALER_amount_set_free (&po->total_amount);
+ TALER_amount_set_free (&po->total_refund_amount);
+ TALER_amount_set_free (&po->total_pending_refund_amount);
GNUNET_free (po->summary_filter);
switch (po->format)
{
@@ -403,16 +395,9 @@ static void
accumulate_total (struct TMH_PendingOrder *po,
const struct TALER_Amount *amount)
{
- if (! po->total_amount_initialized)
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (amount->currency,
- &po->total_amount));
- po->total_amount_initialized = true;
- }
- if (0 > TALER_amount_add (&po->total_amount,
- &po->total_amount,
- amount))
+ if (0 > TALER_amount_set_add (&po->total_amount,
+ amount,
+ NULL))
{
GNUNET_break (0);
po->result = TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT;
@@ -436,27 +421,17 @@ accumulate_refund_totals (struct TMH_PendingOrder *po,
{
if (TALER_EC_NONE != po->result)
return;
- if (! po->total_refund_initialized)
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (refund->currency,
- &po->total_refund_amount));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pending->currency,
- &po->total_pending_refund_amount));
- po->total_refund_initialized = true;
- }
- if (0 > TALER_amount_add (&po->total_refund_amount,
- &po->total_refund_amount,
- refund))
+ if (0 > TALER_amount_set_add (&po->total_refund_amount,
+ refund,
+ NULL))
{
GNUNET_break (0);
po->result = TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT;
return;
}
- if (0 > TALER_amount_add (&po->total_pending_refund_amount,
- &po->total_pending_refund_amount,
- pending))
+ if (0 > TALER_amount_set_add (&po->total_pending_refund_amount,
+ pending,
+ NULL))
{
GNUNET_break (0);
po->result = TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT;
@@ -756,6 +731,8 @@ add_order (void *cls,
size_t len = strlen (contract->summary);
size_t wpos = 0;
char *esummary;
+ struct tm *tm;
+ time_t t;
/* Escape 'summary' to double '"' as per RFC 4180, 2.7. */
esummary = GNUNET_malloc (2 * len + 1);
@@ -765,13 +742,20 @@ add_order (void *cls,
esummary[wpos++] = '"';
esummary[wpos++] = contract->summary[off];
}
-
+ t = GNUNET_TIME_timestamp_to_s (creation_time);
+ tm = localtime (&t);
GNUNET_buffer_write_fstr (
&po->csv,
- "%s,%llu,%llu,%s,%s,%s,\"%s\",%s,%s\r\n",
+ "%s,%llu,%04u-%02u-%02u,%02u:%02u (%s),%llu,%s,%s,%s,\"%s\",%s,%s\r\n",
contract->order_id,
(unsigned long long) order_serial,
- (unsigned long long) GNUNET_TIME_timestamp_to_s (creation_time),
+ tm->tm_year + 1900,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_zone,
+ (unsigned long long) t,
amount_buf,
paid ? refund_buf : "",
paid ? pending_buf : "",
@@ -1070,16 +1054,6 @@ reply_orders (struct TMH_PendingOrder *po,
char refund_buf[128];
char pending_buf[128];
- if (po->total_amount_initialized)
- strcpy (total_buf,
- TALER_amount2s (&po->total_amount));
- if (po->total_refund_initialized)
- strcpy (refund_buf,
- TALER_amount2s (&po->total_refund_amount));
- if (po->total_refund_initialized)
- strcpy (pending_buf,
- TALER_amount2s (&po->total_pending_refund_amount));
-
switch (po->format)
{
case POF_JSON:
@@ -1093,18 +1067,30 @@ reply_orders (struct TMH_PendingOrder *po,
struct MHD_Response *resp;
MHD_RESULT mret;
- GNUNET_buffer_write_fstr (
- &po->csv,
- "Total (paid only),,,%s,%s,%s,,,\r\n",
- po->total_amount_initialized
- ? total_buf
- : "-",
- po->total_refund_initialized
- ? refund_buf
- : "-",
- po->total_refund_initialized
- ? pending_buf
- : "-");
+ for (unsigned int i = 0; i<po->total_amount.taa_size; i++)
+ {
+ struct TALER_Amount *tai = &po->total_amount.taa[i];
+ const struct TALER_Amount *r;
+
+ strcpy (total_buf,
+ TALER_amount2s (tai));
+ r = TALER_amount_set_find (tai->currency,
+ &po->total_refund_amount);
+ strcpy (refund_buf,
+ TALER_amount2s (r));
+ r = TALER_amount_set_find (tai->currency,
+ &po->total_pending_refund_amount);
+ strcpy (pending_buf,
+ TALER_amount2s (r));
+
+ GNUNET_buffer_write_fstr (
+ &po->csv,
+ "Total (paid %s only),,,,%s,%s,%s,,,\r\n",
+ tai->currency,
+ total_buf,
+ refund_buf,
+ pending_buf);
+ }
GNUNET_buffer_write_str (&po->csv,
CSV_FOOTER);
resp = MHD_create_response_from_buffer (po->csv.position,
@@ -1127,23 +1113,37 @@ reply_orders (struct TMH_PendingOrder *po,
struct MHD_Response *resp;
MHD_RESULT mret;
- /* Append totals row with paid and refunded amount columns */
- GNUNET_buffer_write_fstr (
- &po->xml,
- "<Row>"
- "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\">Total (paid only)</Data></Cell>"
- "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\"></Data></Cell>"
- "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\">%s</Data></Cell>"
- "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\">%s</Data></Cell>"
- "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\"></Data></Cell>"
- "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\"></Data></Cell>"
- "</Row>\n",
- po->total_amount_initialized
- ? total_buf
- : "-",
- po->total_refund_initialized
- ? refund_buf
- : "-");
+ for (unsigned int i = 0; i<po->total_amount.taa_size; i++)
+ {
+ struct TALER_Amount *tai = &po->total_amount.taa[i];
+ const struct TALER_Amount *r;
+
+ strcpy (total_buf,
+ TALER_amount2s (tai));
+ r = TALER_amount_set_find (tai->currency,
+ &po->total_refund_amount);
+ strcpy (refund_buf,
+ TALER_amount2s (r));
+ r = TALER_amount_set_find (tai->currency,
+ &po->total_pending_refund_amount);
+ strcpy (pending_buf,
+ TALER_amount2s (r));
+
+ /* Append totals row with paid and refunded amount columns */
+ GNUNET_buffer_write_fstr (
+ &po->xml,
+ "<Row>"
+ "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\">Total (paid %s only)</Data></Cell>"
+ "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\"></Data></Cell>"
+ "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\">%s</Data></Cell>"
+ "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\">%s</Data></Cell>"
+ "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\"></Data></Cell>"
+ "<Cell ss:StyleID=\"Total\"><Data ss:Type=\"String\"></Data></Cell>"
+ "</Row>\n",
+ tai->currency,
+ total_buf,
+ refund_buf);
+ }
GNUNET_buffer_write_str (&po->xml,
XML_FOOTER);
resp = MHD_create_response_from_buffer (po->xml.position,
@@ -1166,27 +1166,43 @@ reply_orders (struct TMH_PendingOrder *po,
/* Build the JSON document for Typst, passing all totals */
json_t *root;
struct TALER_MHD_TypstDocument doc;
-
+ json_t *ta = json_array ();
+ json_t *ra = json_array ();
+ json_t *pa = json_array ();
+
+ GNUNET_assert (NULL != ta);
+ GNUNET_assert (NULL != ra);
+ GNUNET_assert (NULL != pa);
+ for (unsigned int i = 0; i<po->total_amount.taa_size; i++)
+ {
+ struct TALER_Amount *tai = &po->total_amount.taa[i];
+ const struct TALER_Amount *r;
+
+ GNUNET_assert (0 ==
+ json_array_append_new (ta,
+ TALER_JSON_from_amount (tai)));
+ r = TALER_amount_set_find (tai->currency,
+ &po->total_refund_amount);
+ GNUNET_assert (0 ==
+ json_array_append_new (ra,
+ TALER_JSON_from_amount (r)));
+ r = TALER_amount_set_find (tai->currency,
+ &po->total_pending_refund_amount);
+ GNUNET_assert (0 ==
+ json_array_append_new (pa,
+ TALER_JSON_from_amount (r)));
+ }
root = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("business_name",
mi->settings.name),
GNUNET_JSON_pack_array_incref ("orders",
po->pa),
- po->total_amount_initialized
- ? TALER_JSON_pack_amount ("total_amount",
- &po->total_amount)
- : GNUNET_JSON_pack_string ("total_amount",
- "-"),
- po->total_refund_initialized
- ? TALER_JSON_pack_amount ("total_refund_amount",
- &po->total_refund_amount)
- : GNUNET_JSON_pack_string ("total_refund_amount",
- "-"),
- po->total_refund_initialized
- ? TALER_JSON_pack_amount ("total_pending_refund_amount",
- &po->total_pending_refund_amount)
- : GNUNET_JSON_pack_string ("total_pending_refund_amount",
- "-"));
+ GNUNET_JSON_pack_array_steal ("total_amounts",
+ ta),
+ GNUNET_JSON_pack_array_steal ("total_refund_amounts",
+ ra),
+ GNUNET_JSON_pack_array_steal ("total_pending_refund_amounts",
+ pa));
doc.form_name = "orders";
doc.form_version = "0.0.0";
doc.data = root;