UNPKG

@chiper-inc/ecommerce-lib

Version:
222 lines (210 loc) 6.29 kB
import { EventSender, CartEvent } from "../event"; import { getDiscount, getMaximumValue, roundToMultipleQuantity, } from "./helpers"; import { ItemQuantityError } from "./itemQuantityError"; import { New } from './new'; export enum ItemType { PRODUCT = "PRODUCT", COMBO = "COMBO", } export type ItemOptions = { id: number | string; warehouseId: number; name: string; stock: number; image: string; packagingType: string; minQuantity?: number; multipleQuantity?: number; quantity?: number; measurement:{unit:string, quantity:number} }; export abstract class Item extends EventSender { public readonly id: number | string; public readonly warehouseId: number; public readonly type: ItemType; public readonly name: string; protected _quantity?: number; protected _stock: number; public readonly image: string; public readonly packagingType: string; public readonly minQuantity: number; public readonly multipleQuantity: number; public readonly rate: number; private isBackend:boolean | undefined; private isOffline: boolean | undefined; constructor( type: ItemType, { stock, multipleQuantity, name, image, id, warehouseId, packagingType, minQuantity, measurement }: ItemOptions, rate:number, isBackend?: boolean, isOffline?: boolean ) { super(); this.isOffline = isOffline; this.isBackend = isBackend; this.id = id; this.warehouseId = warehouseId; this.type = type; this.name = name; this._stock = stock; this.image = image; let complementPackaging = ''; if (measurement && measurement.quantity && measurement.unit) { complementPackaging = `${measurement.quantity} ${measurement.unit}` complementPackaging = packagingType.includes(complementPackaging) ? '' : ` ${complementPackaging}`; } this.packagingType = `${packagingType}${complementPackaging}`; this.minQuantity = minQuantity ?? 1; this.multipleQuantity = multipleQuantity ?? 1; this.rate = rate; } get stock(): number { return this._stock; } set stock(stock: number) { this._stock = stock; if (this.quantity && this.stock < this.quantity) { this.emit(CartEvent.NEWS, { id: this.id, cardType: this.stock === 0 ? "unavailable" : "lowStock", productType: this.type, medium: this.image, name: this.name, packagingType: this.packagingType, previousTotal: this.regularPrice, quantity: this.quantity, stock: this.stock, total: this.regularPrice, warehouseId: this.warehouseId } as New); } } abstract clone(): Item; set quantity(quantity: number | undefined) { if(quantity == null) { this._quantity = undefined; return; } if (quantity < this.minQuantity && !this.isOffline) { this.emit(CartEvent.BELOW_MIN_QUANTITY, { id: this.id, quantity: quantity, minQuantity: this.minQuantity, }); throw new ItemQuantityError( `Quantity can't be less than minQuantity(${this.minQuantity})`, this.minQuantity, "MinQuantity" ); } if (quantity > this.stock && !this.isOffline) { const newQuantity = getMaximumValue( this.stock, this.maxQuantity ?? this.stock, this.multipleQuantity ); this.emit(CartEvent.OUT_OF_STOCK, { id: this.id, quantity: quantity, stock: this.stock, }); throw new ItemQuantityError( `Quantity can't be more than stock(${this.stock})`, newQuantity, "Stock" ); } if (this.maxQuantity && quantity > this.maxQuantity && !this.isOffline) { const newQuantity = getMaximumValue( this.stock, this.maxQuantity, this.multipleQuantity ); if (this.isBackend === true) { this.quantity = newQuantity; }else{ this.emit(CartEvent.EXCEEDS_MAX_QUANTITY, { id: this.id, quantity: quantity, maxQuantity: this.maxQuantity, }); throw new ItemQuantityError( `Quantity can't be more than maxQuantity(${this.maxQuantity})`, newQuantity, "MaxQuantity" ); } } if (quantity % this.multipleQuantity !== 0 && !this.isOffline) { const newQuantity = roundToMultipleQuantity( quantity, this.multipleQuantity, this.stock ); this.emit(CartEvent.NOT_MULTIPLE_QUANTITY, { id: this.id, quantity: quantity, multipleQuantity: this.multipleQuantity, }); throw new ItemQuantityError( `Quantity can't be different of a multipleQuantity(${this.multipleQuantity})`, newQuantity, "MultipleQuantity" ); } this._quantity = quantity; } get quantity(): number | undefined{ return this._quantity; } /** `discount` is the difference between `regularPrice` and `discountedPrice` in %*/ get discount(): number { return this.discountedPrice ? getDiscount(this.regularPrice, this.discountedPrice) : 0; } abstract get maxQuantity(): number | undefined; abstract get regularPrice(): number; abstract get discountedPrice(): number | undefined; abstract get total(): number | null; abstract get subtotal(): number | null; abstract get chiperPrice(): number; abstract get price(): number; abstract get totalDollars(): number | null; abstract get regularPriceDolar(): number; // create toJson method toJSON() { return { id: this.id, warehouseId: this.warehouseId, type: this.type, name: this.name, stock: this.stock, quantity: this.quantity, image: this.image, medium: this.image, // deprecated packagingType: this.packagingType, minQuantity: this.minQuantity, multipleQuantity: this.multipleQuantity, total: this.total, subtotal: this.subtotal, maxQuantity: this.maxQuantity, maximumQuantity: this.maxQuantity, // deprecated regularPrice: this.regularPrice, discountedPrice: this.discountedPrice, totalDollars: this.totalDollars, regularPriceDolar: this.regularPriceDolar }; } }