merchant

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

taler-merchant-httpd_private-get-statistics-amount-SLUG.c (7633B)


      1 /*
      2   This file is part of TALER
      3   (C) 2025 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-statistics-amount-SLUG.c
     18  * @brief implement GET /statistics-amount/$SLUG/
     19  * @author Martin Schanzenbach
     20  */
     21 #include "platform.h"
     22 #include "taler-merchant-httpd_private-get-statistics-amount-SLUG.h"
     23 #include <gnunet/gnunet_json_lib.h>
     24 #include <taler/taler_json_lib.h>
     25 
     26 
     27 /**
     28  * Typically called by `lookup_statistics_amount_by_bucket`.
     29  *
     30  * @param cls a `json_t *` JSON array to build
     31  * @param description description of the statistic
     32  * @param bucket_start start time of the bucket
     33  * @param bucket_end end time of the bucket
     34  * @param bucket_range range of the bucket
     35  * @param amounts_len the length of @a cumulative_amounts
     36  * @param amounts the cumulative amounts array
     37  */
     38 static void
     39 amount_by_bucket (void *cls,
     40                   const char *description,
     41                   struct GNUNET_TIME_Timestamp bucket_start,
     42                   struct GNUNET_TIME_Timestamp bucket_end,
     43                   const char *bucket_range,
     44                   unsigned int amounts_len,
     45                   const struct TALER_Amount amounts[static amounts_len])
     46 {
     47   json_t *root = cls;
     48   json_t *amount_array;
     49   json_t *buckets_array;
     50 
     51   GNUNET_assert (json_is_object (root));
     52   buckets_array = json_object_get (root,
     53                                    "buckets");
     54   GNUNET_assert (NULL != buckets_array);
     55   GNUNET_assert (json_is_array (buckets_array));
     56 
     57   amount_array = json_array ();
     58   GNUNET_assert (NULL != amount_array);
     59   for (unsigned int i = 0; i < amounts_len; i++)
     60   {
     61     GNUNET_assert (
     62       0 ==
     63       json_array_append_new (amount_array,
     64                              TALER_JSON_from_amount (&amounts[i])));
     65   }
     66 
     67   GNUNET_assert (
     68     0 ==
     69     json_array_append_new (
     70       buckets_array,
     71       GNUNET_JSON_PACK (
     72         GNUNET_JSON_pack_timestamp (
     73           "start_time",
     74           bucket_start),
     75         GNUNET_JSON_pack_timestamp (
     76           "end_time",
     77           bucket_end),
     78         GNUNET_JSON_pack_string (
     79           "range",
     80           bucket_range),
     81         GNUNET_JSON_pack_array_steal (
     82           "cumulative_amounts",
     83           amount_array))));
     84   if (NULL == json_object_get (root,
     85                                "buckets_description"))
     86   {
     87     GNUNET_assert (0 ==
     88                    json_object_set_new (root,
     89                                         "buckets_description",
     90                                         json_string (description)));
     91   }
     92 }
     93 
     94 
     95 /**
     96  * Typically called by `lookup_statistics_amount_by_interval`.
     97  *
     98  * @param cls a `json_t *` JSON array to build
     99  * @param description description of the statistic
    100  * @param bucket_start start time of the bucket
    101  * @param amounts_len the length of @a cumulative_amounts
    102  * @param amounts the cumulative amounts array
    103  */
    104 static void
    105 amount_by_interval (void *cls,
    106                     const char *description,
    107                     struct GNUNET_TIME_Timestamp bucket_start,
    108                     unsigned int amounts_len,
    109                     const struct TALER_Amount amounts[static amounts_len])
    110 {
    111   json_t *root;
    112   json_t *amount_array;
    113   json_t *intervals_array;
    114 
    115   root = cls;
    116   GNUNET_assert (json_is_object (root));
    117   intervals_array = json_object_get (root,
    118                                      "intervals");
    119   GNUNET_assert (NULL != intervals_array);
    120   GNUNET_assert (json_is_array (intervals_array));
    121 
    122   amount_array = json_array ();
    123   GNUNET_assert (NULL != amount_array);
    124   for (unsigned int i = 0; i < amounts_len; i++)
    125   {
    126     GNUNET_assert (
    127       0 ==
    128       json_array_append_new (amount_array,
    129                              TALER_JSON_from_amount (&amounts[i])));
    130   }
    131 
    132 
    133   GNUNET_assert (
    134     0 ==
    135     json_array_append_new (
    136       intervals_array,
    137       GNUNET_JSON_PACK (
    138         GNUNET_JSON_pack_timestamp (
    139           "start_time",
    140           bucket_start),
    141         GNUNET_JSON_pack_array_steal (
    142           "cumulative_amounts",
    143           amount_array))));
    144   if (NULL == json_object_get (root,
    145                                "intervals_description"))
    146   {
    147     GNUNET_assert (
    148       0 ==
    149       json_object_set_new (root,
    150                            "intervals_description",
    151                            json_string (description)));
    152   }
    153 }
    154 
    155 
    156 /**
    157  * Handle a GET "/statistics-amount/$SLUG" request.
    158  *
    159  * @param rh context of the handler
    160  * @param connection the MHD connection to handle
    161  * @param[in,out] hc context with further information about the request
    162  * @return MHD result code
    163  */
    164 MHD_RESULT
    165 TMH_private_get_statistics_amount_SLUG (const struct TMH_RequestHandler *rh,
    166                                         struct MHD_Connection *connection,
    167                                         struct TMH_HandlerContext *hc)
    168 {
    169   struct TMH_MerchantInstance *mi = hc->instance;
    170   json_t *root;
    171   bool get_buckets = true;
    172   bool get_intervals = true;
    173 
    174   GNUNET_assert (NULL != mi);
    175   {
    176     const char *filter;
    177 
    178     filter = MHD_lookup_connection_value (connection,
    179                                           MHD_GET_ARGUMENT_KIND,
    180                                           "by");
    181     if (NULL != filter)
    182     {
    183       if (0 == strcasecmp (filter,
    184                            "bucket"))
    185         get_intervals = false;
    186       else if (0 == strcasecmp (filter,
    187                                 "interval"))
    188         get_buckets = false;
    189       else if (0 != strcasecmp (filter,
    190                                 "any"))
    191       {
    192         GNUNET_break_op (0);
    193         return TALER_MHD_reply_with_error (
    194           connection,
    195           MHD_HTTP_INTERNAL_SERVER_ERROR,
    196           TALER_EC_GENERIC_PARAMETER_MALFORMED,
    197           "by");
    198       }
    199     }
    200   }
    201   root = GNUNET_JSON_PACK (
    202     GNUNET_JSON_pack_array_steal ("intervals",
    203                                   json_array ()),
    204     GNUNET_JSON_pack_array_steal ("buckets",
    205                                   json_array ()));
    206   if (get_buckets)
    207   {
    208     enum GNUNET_DB_QueryStatus qs;
    209 
    210     qs = TMH_db->lookup_statistics_amount_by_bucket (
    211       TMH_db->cls,
    212       mi->settings.id,
    213       hc->infix,
    214       &amount_by_bucket,
    215       root);
    216     if (0 > qs)
    217     {
    218       GNUNET_break (0);
    219       json_decref (root);
    220       return TALER_MHD_reply_with_error (
    221         connection,
    222         MHD_HTTP_INTERNAL_SERVER_ERROR,
    223         TALER_EC_GENERIC_DB_FETCH_FAILED,
    224         "lookup_statistics_amount_by_bucket");
    225     }
    226   }
    227   if (get_intervals)
    228   {
    229     enum GNUNET_DB_QueryStatus qs;
    230 
    231     qs = TMH_db->lookup_statistics_amount_by_interval (
    232       TMH_db->cls,
    233       mi->settings.id,
    234       hc->infix,
    235       &amount_by_interval,
    236       root);
    237     if (0 > qs)
    238     {
    239       GNUNET_break (0);
    240       json_decref (root);
    241       return TALER_MHD_reply_with_error (
    242         connection,
    243         MHD_HTTP_INTERNAL_SERVER_ERROR,
    244         TALER_EC_GENERIC_DB_FETCH_FAILED,
    245         "lookup_statistics_amount_by_interval");
    246     }
    247   }
    248   return TALER_MHD_reply_json (connection,
    249                                root,
    250                                MHD_HTTP_OK);
    251 }
    252 
    253 
    254 /* end of taler-merchant-httpd_private-get-statistics-amount-SLUG.c */