UNPKG

@chiper-inc/ecommerce-lib

Version:
128 lines (113 loc) 3.5 kB
import { count } from "console"; /** * Finds the highest quantity that can be sold of an item adjusted to its `multipleQuantity` * @param stock item stock * @param maxQuantity maximum quantity of this item that can be added * @param multipleQuantity `multipleQuantity` for the item * @returns the highest quantity of the item that can be sold */ export const getMaximumValue = ( stock: number, maxQuantity: number, multipleQuantity: number ): number => { const maxValue = Math.min(stock, maxQuantity); const maxQuantityTimes = Math.floor(maxValue / multipleQuantity) ?? 1; const maxStockMultipleQuantity = maxQuantityTimes * multipleQuantity; return maxStockMultipleQuantity; }; /** * Find the `multipleQuantity` closest to `quantity` * @param quantity amount you want to add * @param multipleQuantity multipleQuantity of this item * @param stock item stock * @returns quantity that complies with the `multiple Quantity` */ export const roundToMultipleQuantity = ( quantity: number, multipleQuantity: number, stock: number ) => { const roundNumber = Math.round(quantity / multipleQuantity) * multipleQuantity; const roundStock = Math.floor(stock / multipleQuantity) * multipleQuantity; return stock < roundNumber ? roundStock : roundNumber; }; export const getDiscount = (regularPrice: number, discountedPrice: number) => ((regularPrice - discountedPrice) / regularPrice) * 100; const min = (a?: number, b?: number): number | undefined => { if (a === undefined) { return b; } if (b === undefined) { return a; } return a < b ? a : b; }; class MaxCounter { private _max?: number; private _count = 0; private _counter?: MaxCounter; constructor(max?: number | null, counter?: MaxCounter) { this._max = max ?? undefined; this._counter = counter; } get max(): number | undefined { return min( this._max ? this._max - this._count : undefined, this._counter?.max ); } get maxAndAdd(): number | undefined { const maxQuantity = this.max; this.add(maxQuantity || 0); return maxQuantity; } set counter(counter: MaxCounter) { this._counter = counter; } add(count: number) { this._count += count; this._counter?.add(count); } } export class MaxQuantityHelper { private readonly _quantity: MaxCounter; private readonly _discounted: MaxCounter; private readonly _scales = new Map(); constructor( productMaxQuantity?: number | null, discountedMaximumQuantity?: number | null ) { this._quantity = new MaxCounter(productMaxQuantity); this._discounted = new MaxCounter( discountedMaximumQuantity, this._quantity ); } private scaleMaxQuantity(counter: MaxCounter, startQuantity = 1, endQuantity?: number) { if (endQuantity) { const scale = this._scales.get(startQuantity); if (scale) { scale.counter = counter; counter = scale; } else { counter = new MaxCounter(endQuantity - startQuantity + 1, counter); this._scales.set(startQuantity, counter); } } return counter.maxAndAdd; } public maxQuantity( startQuantity = 1, endQuantity?: number ): number | undefined { return this.scaleMaxQuantity(this._quantity, startQuantity, endQuantity); } public discountedMaxQuantity( startQuantity = 1, endQuantity?: number ): number | undefined { return this.scaleMaxQuantity(this._discounted, startQuantity, endQuantity); } }