Description


This API provides endpoints for parties that want to implement a shop based on information/functionality available in Fuga:

  • product and stock data
  • client data
  • invoicing functionality


This shop can be an application created by an independent software house on request of a clinic OR it can be the shop module in the myPets application. So basically it is a front-end to the product-offering of the practice and/or its suppliers. It's not an independent legal entity.


TODO: provide backorder mechanism (allow to order/invoice when product not in stock).


A possible usecase is depicted in the below picture.



Endpoints


The base url is https://(testX.)sonetas.eu/fuga/rest/shop/{practiceId}


with {practiceId} the queried practice.


Catalog


Get catalogs


Return the available catalogs for a given practice.


GET catalog


RETURNS

http status 200 ok, returning json array with the available catalog ids


[TPractice,TCatalogA,TCatalogB]


or other http status on error


Get catalog info


Returns info specific for a certain catalog, e.g. logo, color theme, link to general conditions, shipping cost to be applied (cost is determined by practice and can depend on payment method and total amount of order) …


GET catalog/{catalogId}


Product


Get product list


GET catalog/{catalogId}/product/{productType}/{language}/?name=foo&label=bar&currentStock=false


with:

  • productType: TAll, TDrug, TAnimalFood, TAnimalFoodSupplement, TCareProduct, TMaterial
  • and optional parameters
  • language: TDutch, TFrench, TEnglish (determines the language in which product names and units are returned)
  • name: filter on the product name (behaviour: like 'foo%')
  • label: filter on the product label(behaviour: like 'bar%')
  • currentStock: indicate whether the current stock (availableNbrOfUnits) should be returned (default=false)


RETURNS

http status 200 ok, returning json array with product info


{"products":[{"id":2, "name":"zalmbrokken", "cnk":"1234567","type":"TAnimalFood", "unit"="zak", "listPriceExclVat"=12.34, "vatPercentage":21.00, "availableNbrOfUnits":4021},{…}]}


or other http status on error


If availableNbrOfUnits=null, it means that there is no limitation on the available stock.


Note: for catalogId=TPractice only active products that are made available to the shop are returned


Get product detail


GET catalog/{catalogId}/product/{productId}


Also returns the available deliveryMethods for this product (can be different per product: case of wholesaler catalog, but product is in stock at practice and one allows to order in outgoing units of practice => TShippedByWholesaler not possible).


Client


Get client info


GET client/{emailAddress}


with:

  • emailAddress: the email address of the queried person


RETURNS

http status 200 ok, returning json with info of person


{"personId":123, "emailAddress":"dirk@sonetas.eu", "title":"TMr","firstName":"Dirk","lastName":"Ooms", "language"="TDutch", "reduction":5, "streetAndNumber":"", "city":"", "zipCode":"", "country":"TBelgium", "allowMarketingMessages":false}


or http status 404 not found


or other http status on error


Create/update client


POST client

PUT client/{personId}


{"emailAddress":"dirk@sonetas.eu", "title":"TMr","firstName":"Dirk","lastName":"Ooms", "language"="TDutch", "reduction":5, "streetAndNumber":"", "city":"", "zipCode":"", "country":"TBelgium", "companyName":"", "vatNumber":"", "allowMarketingMessages":false}


with:

  • title: TMr, TMrs, TMiss, TDr, TVet, TProf, TFamily, TMrAndMrs,


POST: all fields are mandatory, except companyName and vatNumber

PUT: only specified fields are updated


RETURNS

http 200 ok with

{"personId":123}


or other http code on error


Get invoices


GET client/{personId}/invoice?startDate=20200701&endDate=20200731


with startDate and endDate optional


RETURNS

http status 200 ok, returning json array with summarized invoices info


{"invoices":[{"id":2, "number":"FA.000123", "date":"2020-07-02"},{"id":9, "number":"FA.000131", "date":"2020-07-12"},…]}


or other http status on error


Get orders


GET client/{personId}/order?startDate=20200701&endDate=20200731


with startDate and endDate optional


RETURNS

http status 200 ok, returning json array with summarized order info


{"orders":[{"id":1, "number":"OR.4", "date":"2020-07-09"},{"id":3, "number":"OR.5", "date":"2020-07-16"},…]}


or other http status on error


Order


Create an order


POST catalog/{catalogId}/order


{"personId":123,"orders":[{"productId":56, "nbrOfUnits":1, "reductionApplied":5, "sellingPriceExclVat":12.23, "vatAmount":2.57}, …], "amountPaid":5.00, "paymentMethod":"TCreditcard", "deliveryMethod": "TPickupAtPractice", "description":"freeTextMessage", "createInvoice":true}


with:

- person: if 'id' is known (!=0), it is sufficient to send the id. if 'id' is not known (=0) info of the person needs to be provided ()

- paymentMethod: TBancontact, TCreditcard, TMollie, …

- deliveryMethod: THandledByShop, TPickupAtPractice, TShippedByPractice, TShippedByWholesaler (only if catalogId!=TPractice)


RETURNS

http 200 ok with

{"orderIds":[123,124], "invoiceId":567}


with:

- the orderId and invoiceId being unique within a practice.


or other http code on error


Get invoice


GET invoice/{invoiceId}


RETURNS

http status 200 ok, returning json object with invoice info


{"id":2, "number":"FA.000123", "date":"2020-07-02", "amount":34.34,"pdfDocument":"BASE64ENCODEDPDFDOCUMENT"}


with:

- pdfDocument: base64 encoded


or other http status on error


Get order


GET order/{orderId}


RETURNS

http status 200 ok, returning json object with invoice info


{"id":1, "number":"OR.2", "date":"2020-07-13", "products":[{"name":"productA", "status":"TOrdered"},{"name":"productB", "status":"TCollected"}],"pdfDocument":"BASE64ENCODEDPDFDOCUMENT"}


with:

- pdfDocument: base64 encoded


or other http status on error


Wholesaler shops


A practice can expose its own stock in the shop, but it's also possible for third parties (typically wholesalers of the practice) to expose their catalog via this shop API.


It is up to the practice to decide which catalog(s) is/are exposed. Payment and invoicing to the customer is handled by the shop and/or the practice (not by the wholesaler).


The practice does the price setting based on margins on the public price or gross price (this margin can be set by the practice per product type). There is an option for the practice to 'overrule' an item in the wholesaler catalog by an item in its own stock/catalog.


Question: to which extent does the wholesaler want to be visible in the shop? own logo, theme (remark: is wholesaler known by the pet owner?)? or just mentioning 'powered by WholesalerA' and shop presented as shop of practice.

Question: at the moment we are inclined to allow only 1 catalog to be selected, else it could become confusing to the pet owner. Opinion wholesaler?


If a wholesaler wants to integrate with this mechanism the wholesaler should offer below web services. If a wholesaler already integrates with fuga for ordering (practice orders within Fuga products at wholesaler) most web services will already be more or less available, so the required effort to enter the system is rather low.


At the moment we assume a 'retour' is always handled by bringing the product back to the practice.


Get catalog


The catalog is provided in xml or json format. This typically will include:

  • product name
  • product type (and subtype)
  • description
  • publicPrice
  • link(s) to picture
  • link(s) to video


To enhance the user interface (filtering) it is good to have as much information as possible, e.g.:

  • promotion/new
  • target species
  • age category
  • indication
  • animal size
  • producer


A catalog can be language-specific.


Create order


This method should allow to order a product based on the article code in the catalog. It must be a real order (not adding to shopping basket). If wholesaler offers home delivery, this can be indicated. This method must return a wholesaler specific orderId.


Get order status


Get the current status of certain order based on an orderId.


Get list of orders


Get a list of the currently open orders (i.e. not yet completed) for the practice


Usecase