UNPKG

@dutchfurniturefulfilment/skik-client

Version:

Javascript package for integrating a SKIK configurator inside web projects.

148 lines (108 loc) 5.95 kB
# Injecting product prices and displaying a total price The SKIK configurator has built-in facilities to automatically calculate total prices depending on the parts selected by a configurator user. In order for the configurator to do this, the prices must be explicitly given to a `Client` instance. ## Global rules concerning the expression of prices - All prices are expected to be in the [**EUR** currency](https://en.wikipedia.org/wiki/Euro) at all times. - All prices are expected to **include** [VAT](https://en.wikipedia.org/wiki/Value-added_tax). _Value-added Tax, BTW in the Netherlands._ - All price values are expected to be quantified in the **cents unit**. _For example: **EUR 12,50** is expressed as `1250`. In code, prices are at all times expected to be of type `Number`._ - 2 prices are used for all products: - **Original price** - **Is** the price for a product, **excluding any discount**. - **Is** by convention named `originalPrice` in code. - **Discount price** - **Is** the price for a product, **including potential discount**. - **Is** by convention named `discountPrice` in code. ## Expressing price discounts, or absence thereof If a certain product has no applicable discount, **discount-price** must for that product equal **original-price**. In any case, both properties are required to keep API signatures consistent: ```typescript const productWithDiscount: SKIKClient.ProductPrices = { EANCode: "8714713074655", originalPrice: 1250, discountPrice: 1050, }; // Products without discount have the `discountPrice` // value set to the same value as `originalPrice`: const productWithoutDiscount: SKIKClient.ProductPrices = { EANCode: "8714713074662", originalPrice: 1600, discountPrice: 1600, }; ``` ## Injecting product prices **Only if prices for _all products_ are given, the configurator will attempt to calculate the sum of prices for any given configuration.** If price-data is not given, or is incomplete, no relative prices can be shown in the configurator interface, and no [`"price-changed"` events](../api/event-channels#price-changed) can be dispatched by the client instance. ### Retrieving EAN codes for all relevant products The [`Client # getEANCodes()`](../api/client#getting-an-array-of-all-product-ean-codes) method can be used to obtain an array of all EAN codes for products that are used in the SKIK configurator. The method returns a `Promise` that resolves to the array of codes: ```typescript const skikClient: SKIKClient.Client = SKIKClient.create({ /* ... */ }); const EANCodesPromise: Promise<string[]> = skikClient.getEANCodes(); /* => [ "8714713074655", "8714713074662", "8714713074679", // ... ]; */ ``` _After retrieval, this returned array can be used as source for your price data query._ Let's assume a function called `pricesForEANCode` exists, that returns an object implementing the [`SKIKClient.ProductPrices`](../interfaces/prices#productprices) interface: a plain object as returned in this **pseudo-implementation**: _In reality, product prices would of course be dynamically determined based on the given EAN code, instead of literal numbers._ ```typescript const pricesForEANCode = (code: string): SKIKClient.ProductPrices => ({ EANCode, originalPrice: 1250, discountPrice: 1050, }); ``` ### Feeding back all required prices into the configurator With our price retrieval implementation in place, it's time to decorate the `EANCodes` array we retrieved a Promise for earlier. This example uses `pricesForEANCode` to perform a map operation on the array of EAN codes: ```typescript EANCodesPromise.then(function(EANCodes) { const productData: SKIKClient.ProductPrices[] = EANCodes.map(function(code) { return pricesForEANCode(code); }); // ... }) ``` The `productData` variable should now be in the exact format expected by [`Client # setProductPrices()`](../api/client#setting-the-prices-for-products), the method we'll use to inject the price data. ```typescript // Like before: EANCodesPromise.then(function(EANCodes) { const prices: SKIKClient.ProductPrices[] = EANCodes.map(function(code) { return pricesForEANCode(code); }); // But with injection: skikClient.setProductPrices(prices); // The data is formatted like this: assert.equal(prices, [ { EANCode: "8714713074655", originalPrice: 1250, discountPrice: 1050 }, { EANCode: "8714713074662", originalPrice: 1600, discountPrice: 1600 }, { EANCode: "8714713074679", originalPrice: 995, discountPrice: 995 }, // ... ]); }); ``` ## Displaying a total price The configurator does not implement a display of the total configuration price. Instead, it emits the [`"price-changed"`](../interfaces/event-channels#price-changed) event each time a mutation of the total price occurred. We can listen to these events to get [price mutation reports](../interfaces/prices#pricemutationreport) providing valuable information about the old and new prices: ```typescript skikClient.on("price-changed", (mutationReport) => { // Example data: assert.equal(mutationReport, { before: { originalPrice: { cents: 1250, formatted: "€12,50" }, discountPrice: { cents: 1050, formatted: "€10,50" }, }, after: { originalPrice: { cents: 2500, formatted: "€25,00" }, discountPrice: { cents: 2100, formatted: "€21,00" }, }, }); console.log(`The previous real price (including discount) was: `, mutationReport.before.discountPrice.formatted); // > "The previous real price (including discount) was: €10,50" console.log(`The new real price (including discount) is: `, mutationReport.after.discountPrice.formatted); // > "The new real price (including discount) is: €21,00" }); ```