import { Price } from "./price"; import { Item, ItemType } from "./item"; import { Product } from "./product"; import { Promotion } from "./promotion"; import { ItemQuantityError } from "./itemQuantityError"; type CartOptions = { items: Item[]; storeId: number; warehouseId: number; locationId: number; status: "OK" | "IN_PROGRESS"; }; class Cart { private _items: Item[]; public readonly storeId: number; public readonly warehouseId: number; public readonly locationId: number; public readonly status: "OK" | "IN_PROGRESS"; constructor({ items, storeId, warehouseId, status, locationId, }: CartOptions) { this._items = items; this.storeId = storeId; this.warehouseId = warehouseId; this.status = status; this.locationId = locationId; } get items(): Item[] { return this._items; } get total(): number { return +this.items .reduce((total: number, item: Item) => total + item.total, 0) .toFixed(2); } get subtotal(): number { return +this.items .reduce((subtotal: number, item: Item) => subtotal + item.subtotal, 0) .toFixed(2); } removeItem(id: number | string) { this._items = this._items.filter((item) => item.id !== id); } addItem(item: Item) { this._items.push(item); } /* eslint-disable @typescript-eslint/no-explicit-any */ static from({ items, storeId, warehouseId, status, locationId }: any): Cart { return new Cart({ items: items.map((itemRaw: any) => { let item: Item; switch (itemRaw.type) { case ItemType.PRODUCT: item = Product.from(itemRaw); break; case ItemType.COMBO: item = Promotion.from(itemRaw); break; default: throw new Error("invalid productType: " + itemRaw.productType); } return item; }), storeId, warehouseId, status, locationId, }); } static fromShopCart({ carts, storeId, warehouseId, status, locationId, }: 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 }) ); break; case ItemType.COMBO: item = Promotion.fromShopCart(itemRaw); break; default: throw new Error("invalid productType: " + itemRaw.productType); } return item; }), storeId, warehouseId, status, locationId, }); } // 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, subtotal: this.subtotal, news: [], }; } } export { Price, Item, Product, Promotion, Cart, CartOptions, ItemQuantityError, };