UNPKG

@chiper-inc/ecommerce-lib

Version:
192 lines (178 loc) 4.56 kB
import { Price } from "./price"; import { Item, ItemType } from "./item"; import { Product, Measurement } from "./product"; import { Promotion } from "./promotion"; import { ItemQuantityError } from "./itemQuantityError"; import { New } from './new'; import { MaxQuantityHelper } from './helpers'; type CartOptions = { items: Item[]; storeId: number; warehouseId: number; locationId: number; status: "OK" | "IN_PROGRESS"; rate?: number }; class Cart { private _items: Item[]; private _rate: number; public readonly storeId: number; public readonly warehouseId: number; public readonly locationId: number; public readonly status: "OK" | "IN_PROGRESS"; public news: New[] = []; constructor({ items, storeId, warehouseId, status, locationId, rate }: CartOptions) { this._items = items; this.storeId = storeId; this.warehouseId = warehouseId; this.status = status; this.locationId = locationId; this._rate = 1 if (rate) { this._rate = rate; } } get rate(): number { return this._rate; } get items(): Item[] { return this._items; } get totalDollars(): number{ return +this.items .reduce((total: number, item: Item) => total + (item.totalDollars ?? 0), 0) .toFixed(2); } get total(): number { return +this.items .reduce((total: number, item: Item) => total + (item.total ?? 0), 0) .toFixed(2); } get subtotal(): number { return +this.items .reduce( (subtotal: number, item: Item) => subtotal + (item.subtotal ?? 0), 0 ) .toFixed(2); } removeItem(id: number | string) { this._items = this._items.filter((item) => item.id !== id); } addItem(item: Item) { this._items.push(item); } get margin(): number { const profit = +this.items .reduce((total: number, item: Item) => ((item.price - item.chiperPrice) * (item.quantity || 0) + total), 0); return +(profit / this.subtotal).toFixed(2); } getCartForWarehouse(warehouseId: number): Cart { return new Cart({ items: this.itemsByWarehouseId(warehouseId), storeId: this.storeId, warehouseId: warehouseId, status: this.status, locationId: this.locationId, }); } itemsByWarehouseId(warehouseId: number): Item[]{ return this._items.filter((item) => item.warehouseId === warehouseId) } /* eslint-disable @typescript-eslint/no-explicit-any */ static from({ items, storeId, warehouseId, status, locationId }: any, rate:number, isBackend?: boolean, isOffline?: boolean): Cart { return new Cart({ items: items.map((itemRaw: any) => { let item: Item; switch (itemRaw.type) { case ItemType.PRODUCT: { item = Product.from(itemRaw, rate, isBackend, isOffline); break; } case ItemType.COMBO: item = Promotion.from(itemRaw, rate); break; default: throw new Error("invalid productType: " + itemRaw.productType); } return item; }), storeId, warehouseId, status, locationId, rate }); } static fromShopCart({ carts, storeId, warehouseId, status, locationId, rate }: any): Cart { return new Cart({ items: carts[0].items.map((itemRaw: any) => { let item: Item; switch (itemRaw.productType) { case ItemType.PRODUCT: { item = Product.fromShopCart( Object.assign({}, itemRaw, { prices: itemRaw.products[0].prices }), rate ); break; } case ItemType.COMBO: item = Promotion.fromShopCart(itemRaw, rate); break; default: throw new Error("invalid productType: " + itemRaw.productType); } return item; }), storeId, warehouseId, status, locationId, rate }); } // toJSON function toJSON() { return { items: this.items.map((item) => item.toJSON()), storeId: this.storeId, warehouseId: this.warehouseId, status: this.status, locationId: this.locationId, total: this.total, totalDollars: this.totalDollars, subtotal: this.subtotal, news: this.news, rate: this.rate }; } } export { Price, Item, Product, Promotion, Cart, CartOptions, ItemQuantityError, Measurement, MaxQuantityHelper, };