import * as _ from 'lodash'; import { Product } from '../product/product'; export interface ExportMe { } export class CartItem { public cost: number; // public courseId: string; public static fromJson (obj: any) { return new CartItem( Product.inCartFromJson(obj), obj.quantity, obj.courseId ? obj.courseId: null, obj.size ? obj.size: null, obj.colour ? obj.colour: null, Product.inCartFromJson(obj).getPrinter() ); } public toJson() { let cartItem: any = this.product.toJson(); cartItem.quantity = this.getQuantity(); if(this.courseId) cartItem.courseId = this.courseId; if(this.printer) cartItem.printer = this.printer; return cartItem; } // public printer_toJson(){ // let printerJson: any = { // belonging: this.printer["belonging"], // status: this.printer["status"] // } // return printerJson; // } // public printer_fromJson(obj: any){ // if ( obj ){ // return JSON.parse(obj); // } // else // return null; // } constructor( // TODO have a unique itemId for each CartItem public product: Product , public quantity: number , public courseId?: string , public size?: string , public colour?: string , public printer?: object ) { this.cost = this.product.getPrice() * this.quantity; } updateItemQuantity(updatedQuantity: number) { this.quantity = updatedQuantity; this.cost = this.product.getPrice() * this.quantity; } getCost() { return this.cost; } getProduct() { return this.product; } getQuantity() { return this.quantity; } getSize() { return this.size; } getColour() { return this.colour; } getCourseId() { return this.courseId? this.courseId: null; } getPrinter() { return this.printer? this.printer: null; } } export class Cart { public cartCost: number = 0; private numItems: number; public static fromJson (obj: any) { const items = _.chain(obj.items).values().map(CartItem.fromJson).value(); return new Cart(Number(obj.numItems), obj.storeId, obj.tenantId, obj.userId, items, obj.status, obj.id, obj.tableId, obj.created, obj.__v, obj._rev); } public toJson() { const cartJson: any = { __v: this.__v ? this.__v : '', userId: this.userId, tenantId: this.tenantId, id: this.id, created: this.created ? this.created : '', items: [] , // carItems to json numItems: this.getItemsCount(), total: this.getCartCost(), storeId: this.storeId, status: this.status, tableId: this.tableId }; if(this._rev) cartJson._rev = this._rev; return cartJson; } constructor( numItems: number , public storeId?: string // TODO should be a Store instance when we have that , public tenantId?: string , public userId?: string , public cartItems?: CartItem[] , public status?: string , public id?: string , public tableId?: string , public created?: string , public __v?: string , public _rev?: string ) { this.numItems = (_.isUndefined(numItems) || numItems == null? 0 : numItems ); this.calculateCartCost(); if (this.id === undefined) { this.id = ''; } } public calculateCartCost() { this.cartCost = 0; this.cartItems.forEach( (cItem: CartItem) => { this.cartCost += cItem.getCost(); }); } private findItemInCartItems(keyItem: CartItem) { return _.find(this.cartItems, (cItem: CartItem) => { return cItem.getProduct().getId() === keyItem.getProduct().getId(); }); } private findProductInCartItems(keyId: string) { return _.find(this.cartItems, (cItem: CartItem) => { return cItem.getProduct().getId() === keyId; }); } addCartItem(newItem: CartItem) { let foundItem: CartItem = this.findItemInCartItems(newItem); const position = this.cartItems.findIndex((item) => { return item.getProduct().getId() === newItem.getProduct().getId(); }); this.numItems+= newItem.getQuantity(); if (foundItem) { //foundItem.updateItemQuantity(foundItem.getQuantity() + newItem.getQuantity()); this.cartItems[position].updateItemQuantity(foundItem.getQuantity() + newItem.getQuantity()); }else { this.cartItems.push(newItem); } this.calculateCartCost(); } removeCartItem(idOfProductToRemove: string) { let indexOfItemToRemove = _.findIndex(this.cartItems, (cItem: CartItem) => { return cItem.getProduct().getId() === idOfProductToRemove; }); if (indexOfItemToRemove === -1) { // Case of failure console.error('Failed to remove product with id "' + idOfProductToRemove + '". Product was not found in cartItems[].'); }else { // Case of proceeding as normal this.numItems -= this.cartItems[indexOfItemToRemove].getQuantity(); this.cartItems.splice(indexOfItemToRemove, 1); this.calculateCartCost(); } } getItem(prodId: string) { const indexOfItem = _.findIndex(this.cartItems, (cItem: CartItem) => { return cItem.getProduct().getId() === prodId; }); return this.cartItems[indexOfItem]; } incrementQuantity(prodId: string) { let foundItem: CartItem = this.findProductInCartItems(prodId); foundItem.updateItemQuantity(foundItem.getQuantity() + 1); this.setItemsCount(); this.calculateCartCost(); return foundItem; } decrementQuantity(prodId: string) { let foundItem: CartItem = this.findProductInCartItems(prodId); foundItem.updateItemQuantity(foundItem.getQuantity() - 1); this.setItemsCount(); this.calculateCartCost(); return foundItem; } // getItemsCount() { return this.cartItems.length; } setItemsCount() { this.numItems = this.getCartItems().map(a => a.getQuantity()).reduce((a,b) => a+b, 0); } getItemsCount() { return this.numItems; } getStoreId() { return this.storeId; } getStatus() { return this.status; } getCartItems() { return this.cartItems; } getCartCost() { return this.cartCost; } getTableId() { return this.tableId; } }