merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit a22d66a2a8614efca9f505cd0097e162febce670
parent 11d0700360eb768d4cf502eea6be4c253702570d
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 16 Mar 2026 22:12:18 +0100

fix #11253

Diffstat:
Msrc/backend/taler-merchant-httpd_get-private-orders.c | 214++++++++++++++++++++++++++++++++++++++++++-------------------------------------
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;