gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 01/02: implement merchant v16


From: gnunet
Subject: [taler-wallet-core] 01/02: implement merchant v16
Date: Thu, 01 Aug 2024 17:17:22 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit 24c6d46d34de6b42fe6434d0a5ab4f405c86f27d
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Aug 1 12:16:34 2024 -0300

    implement merchant v16
---
 packages/taler-util/src/http-client/merchant.ts | 177 +++++++++++++++++++++++-
 packages/taler-util/src/types-taler-merchant.ts | 117 ++++++++++++++--
 2 files changed, 283 insertions(+), 11 deletions(-)

diff --git a/packages/taler-util/src/http-client/merchant.ts 
b/packages/taler-util/src/http-client/merchant.ts
index 1b2d39dcc..3260c1546 100644
--- a/packages/taler-util/src/http-client/merchant.ts
+++ b/packages/taler-util/src/http-client/merchant.ts
@@ -32,6 +32,8 @@ import {
   codecForAccountKycRedirects,
   codecForAccountsSummaryResponse,
   codecForBankAccountDetail,
+  codecForCategoryListResponse,
+  codecForCategoryProductList,
   codecForClaimResponse,
   codecForInstancesResponse,
   codecForInventorySummaryResponse,
@@ -99,6 +101,9 @@ export enum TalerMerchantInstanceCacheEviction {
   CREATE_PRODUCT,
   UPDATE_PRODUCT,
   DELETE_PRODUCT,
+  CREATE_CATEGORY,
+  UPDATE_CATEGORY,
+  DELETE_CATEGORY,
   CREATE_TRANSFER,
   DELETE_TRANSFER,
   CREATE_DEVICE,
@@ -132,7 +137,7 @@ export enum TalerMerchantManagementCacheEviction {
  * Uses libtool's current:revision:age versioning.
  */
 export class TalerMerchantInstanceHttpClient {
-  public readonly PROTOCOL_VERSION = "15:0:0";
+  public readonly PROTOCOL_VERSION = "16:0:0";
 
   readonly httpLib: HttpRequestLibrary;
   readonly cacheEvictor: CacheEvictor<TalerMerchantInstanceCacheEviction>;
@@ -792,6 +797,172 @@ export class TalerMerchantInstanceHttpClient {
   // Inventory Management
   //
 
+  /**
+   * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-categories
+   */
+  async listCategories(token: AccessToken, params?: PaginationParams) {
+    const url = new URL(`private/categories`, this.baseUrl);
+
+    // addMerchantPaginationParams(url, params);
+
+    const headers: Record<string, string> = {};
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token);
+    }
+    const resp = await this.httpLib.fetch(url.href, {
+      method: "GET",
+      headers,
+    });
+
+    switch (resp.status) {
+      case HttpStatusCode.Ok:
+        return opSuccessFromHttp(resp, codecForCategoryListResponse());
+        case HttpStatusCode.NotFound: 
+        return opKnownHttpFailure(resp.status, resp);
+        case HttpStatusCode.Unauthorized: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+    }
+  }
+
+  /**
+   * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-categories-$CATEGORY_ID
+   */
+  async getCategoryDetails(token: AccessToken | undefined, cId: string) {
+    const url = new URL(`private/categories/${cId}`, this.baseUrl);
+
+    const headers: Record<string, string> = {};
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token);
+    }
+    const resp = await this.httpLib.fetch(url.href, {
+      method: "GET",
+      headers,
+    });
+
+    switch (resp.status) {
+      case HttpStatusCode.Ok:
+        return opSuccessFromHttp(resp, codecForCategoryProductList());
+      case HttpStatusCode.Unauthorized: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      case HttpStatusCode.NotFound:
+        return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+    }
+  }
+
+  /**
+   * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-categories
+   */
+  async addCategory(
+    token: AccessToken | undefined,
+    body: TalerMerchantApi.CategoryCreateRequest,
+  ) {
+    const url = new URL(`private/categories`, this.baseUrl);
+
+    const headers: Record<string, string> = {};
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token);
+    }
+    const resp = await this.httpLib.fetch(url.href, {
+      method: "POST",
+      body,
+      headers,
+    });
+
+    switch (resp.status) {
+      case HttpStatusCode.Ok: {
+        this.cacheEvictor.notifySuccess(
+          TalerMerchantInstanceCacheEviction.CREATE_CATEGORY,
+        );
+        return opEmptySuccess(resp);
+      }
+      case HttpStatusCode.Unauthorized: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      case HttpStatusCode.NotFound: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      // case HttpStatusCode.Conflict:
+      //   return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+    }
+  }
+
+  /**
+   * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-categories
+   */
+  async updateCategory(
+    token: AccessToken | undefined,
+    cid: string,
+    body: TalerMerchantApi.CategoryCreateRequest,
+  ) {
+    const url = new URL(`private/categories/${cid}`, this.baseUrl);
+
+    const headers: Record<string, string> = {};
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token);
+    }
+    const resp = await this.httpLib.fetch(url.href, {
+      method: "PATCH",
+      body,
+      headers,
+    });
+
+    switch (resp.status) {
+      case HttpStatusCode.NoContent: {
+        this.cacheEvictor.notifySuccess(
+          TalerMerchantInstanceCacheEviction.UPDATE_CATEGORY,
+        );
+        return opEmptySuccess(resp);
+      }
+      case HttpStatusCode.Unauthorized: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      case HttpStatusCode.NotFound: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      // case HttpStatusCode.Conflict:
+      //   return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+    }
+  }
+
+
+  /**
+   * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-categories-$CATEGORY_ID
+   */
+  async deleteCategory(token: AccessToken | undefined, cId: string) {
+    const url = new URL(`private/categories/${cId}`, this.baseUrl);
+
+    const headers: Record<string, string> = {};
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token);
+    }
+    const resp = await this.httpLib.fetch(url.href, {
+      method: "DELETE",
+      headers,
+    });
+
+    switch (resp.status) {
+      case HttpStatusCode.NoContent: {
+        this.cacheEvictor.notifySuccess(
+          TalerMerchantInstanceCacheEviction.DELETE_CATEGORY,
+        );
+        return opEmptySuccess(resp);
+      }
+      case HttpStatusCode.Unauthorized: // FIXME: missing in docs
+        return opKnownHttpFailure(resp.status, resp);
+      case HttpStatusCode.NotFound:
+        return opKnownHttpFailure(resp.status, resp);
+      // case HttpStatusCode.Conflict:
+      //   return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+    }
+  }
+
+
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-products
    */
@@ -952,7 +1123,7 @@ export class TalerMerchantInstanceHttpClient {
   }
 
   /**
-   * https://docs.taler.net/core/api-merchant.html#reserving-inventory
+   * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-products-$PRODUCT_ID-lock
    */
   async lockProduct(
     token: AccessToken | undefined,
@@ -990,7 +1161,7 @@ export class TalerMerchantInstanceHttpClient {
   }
 
   /**
-   * 
https://docs.taler.net/core/api-merchant.html#removing-products-from-inventory
+   * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-products-$PRODUCT_ID
    */
   async deleteProduct(token: AccessToken | undefined, productId: string) {
     const url = new URL(`private/products/${productId}`, this.baseUrl);
diff --git a/packages/taler-util/src/types-taler-merchant.ts 
b/packages/taler-util/src/types-taler-merchant.ts
index 33c383a95..38d17b8c0 100644
--- a/packages/taler-util/src/types-taler-merchant.ts
+++ b/packages/taler-util/src/types-taler-merchant.ts
@@ -1455,6 +1455,64 @@ export interface BankAccountDetail {
   active?: boolean;
 }
 
+export interface CategoryListResponse {
+  // Array with all of the categories we know.
+  categories: CategoryListEntry[];
+}
+
+export interface CategoryListEntry {
+  // Unique number for the category.
+  category_id: Integer;
+
+  // Name of the category.
+  name: string;
+
+  // Translations of the name into various
+  // languages.
+  name_i18n?: { [lang_tag: string]: string };
+
+  // Number of products in this category.
+  // A product can be in more than one category.
+  product_count: Integer;
+}
+
+export interface CategoryProductList {
+  // Name of the category.
+  name: string;
+
+  // Translations of the name into various
+  // languages.
+  name_i18n?: { [lang_tag: string]: string };
+
+  // The products in this category.
+  products: ProductSummary[];
+}
+
+export interface ProductSummary {
+  // Product ID to use.
+  product_id: string;
+
+  // Human-readable product description.
+  description: string;
+
+  // Map from IETF BCP 47 language tags to localized descriptions.
+  description_i18n?: { [lang_tag: string]: string };
+}
+
+export interface CategoryCreateRequest {
+  // Name of the category.
+  name: string;
+
+  // Translations of the name into various
+  // languages.
+  name_i18n?: { [lang_tag: string]: string };
+}
+
+export interface CategoryCreatedResponse {
+  // Number of the newly created category.
+  category_id: Integer;
+}
+
 export interface ProductAddDetail {
   // Product ID to use.
   product_id: string;
@@ -1465,6 +1523,11 @@ export interface ProductAddDetail {
   // Map from IETF BCP 47 language tags to localized descriptions.
   description_i18n?: { [lang_tag: string]: string };
 
+  // Categories into which the product belongs.
+  // Used in the POS-endpoint.
+  // Since API version **v16**.
+  categories?: Integer[];
+
   // Unit in which the product is measured (liters, kilograms, packages, etc.).
   unit: string;
 
@@ -1504,6 +1567,11 @@ export interface ProductPatchDetail {
   // Map from IETF BCP 47 language tags to localized descriptions.
   description_i18n?: { [lang_tag: string]: string };
 
+  // Categories into which the product belongs.
+  // Used in the POS-endpoint.
+  // Since API version **v16**.
+  categories?: Integer[];
+
   // Unit in which the product is measured (liters, kilograms, packages, etc.).
   unit: string;
 
@@ -1623,6 +1691,10 @@ export interface ProductDetail {
   // Unit in which the product is measured (liters, kilograms, packages, etc.).
   unit: string;
 
+  // Categories into which the product belongs.
+  // Since API version **v16**.
+  categories: Integer[];
+
   // The price for one unit of the product. Zero is used
   // to imply that this product is not sold separately, or
   // that the price is not fixed, and must be supplied by the
@@ -2734,14 +2806,15 @@ const codecForExchangeConfigInfo = (): 
Codec<ExchangeConfigInfo> =>
     .property("master_pub", codecForString())
     .build("TalerMerchantApi.ExchangeConfigInfo");
 
-export const codecForTalerMerchantConfigResponse = (): 
Codec<TalerMerchantConfigResponse> =>
-  buildCodecForObject<TalerMerchantConfigResponse>()
-    .property("name", codecForConstString("taler-merchant"))
-    .property("currency", codecForString())
-    .property("version", codecForString())
-    .property("currencies", codecForMap(codecForCurrencySpecificiation()))
-    .property("exchanges", codecForList(codecForExchangeConfigInfo()))
-    .build("TalerMerchantApi.VersionResponse");
+export const codecForTalerMerchantConfigResponse =
+  (): Codec<TalerMerchantConfigResponse> =>
+    buildCodecForObject<TalerMerchantConfigResponse>()
+      .property("name", codecForConstString("taler-merchant"))
+      .property("currency", codecForString())
+      .property("version", codecForString())
+      .property("currencies", codecForMap(codecForCurrencySpecificiation()))
+      .property("exchanges", codecForList(codecForExchangeConfigInfo()))
+      .build("TalerMerchantApi.VersionResponse");
 
 export const codecForClaimResponse = (): Codec<ClaimResponse> =>
   buildCodecForObject<ClaimResponse>()
@@ -2941,6 +3014,33 @@ export const codecForBankAccountDetail = (): 
Codec<BankAccountDetail> =>
     .property("active", codecOptional(codecForBoolean()))
     .build("TalerMerchantApi.BankAccountEntry");
 
+export const codecForCategoryListResponse = (): Codec<CategoryListResponse> =>
+  buildCodecForObject<CategoryListResponse>()
+    .property("categories", codecForList(codecForCategoryListEntry()))
+    .build("TalerMerchantApi.CategoryListResponse");
+
+export const codecForCategoryListEntry = (): Codec<CategoryListEntry> =>
+  buildCodecForObject<CategoryListEntry>()
+    .property("category_id", codecForNumber())
+    .property("name", codecForString())
+    .property("name_i18n", codecForInternationalizedString())
+    .property("product_count", codecForNumber())
+    .build("TalerMerchantApi.CategoryListEntry");
+
+export const codecForCategoryProductList = (): Codec<CategoryProductList> =>
+  buildCodecForObject<CategoryProductList>()
+    .property("name", codecForString())
+    .property("name_i18n", codecForInternationalizedString())
+    .property("products", codecForList(codecForProductSummary()))
+    .build("TalerMerchantApi.CategoryProductList");
+
+export const codecForProductSummary = (): Codec<ProductSummary> =>
+  buildCodecForObject<ProductSummary>()
+    .property("product_id", codecForString())
+    .property("description", codecForString())
+    .property("description_i18n", codecForInternationalizedString())
+    .build("TalerMerchantApi.ProductSummary");
+
 export const codecForInventorySummaryResponse =
   (): Codec<InventorySummaryResponse> =>
     buildCodecForObject<InventorySummaryResponse>()
@@ -2990,6 +3090,7 @@ export const codecForProductDetail = (): 
Codec<ProductDetail> =>
     .property("unit", codecForString())
     .property("price", codecForAmountString())
     .property("image", codecForString())
+    .property("categories", codecForList(codecForNumber()))
     .property("taxes", codecOptional(codecForList(codecForTax())))
     .property("address", codecOptional(codecForLocation()))
     .property("next_restock", codecOptional(codecForTimestamp))

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]