const shared_consts = require('../tools/shared_nodejs'); const cartModel = require('../models/cart') const { ObjectID } = require('mongodb'); const Gasordine = require('../models/gasordine'); const Order = require('../models/order'); class Cart { constructor(order, arrorders) { this.modify_at = new Date(); this.items = {}; if (!!order) { this.initializeFromOrder(order); } else if (!!arrorders) { for (const ord of arrorders) { this.items.push(ord) } } this.updatecarttotals(false); } initializeFromOrder(order) { this.idapp = order.idapp || 0; this.userId = order.userId || ""; this.items[order._id] = order; } static constructByCart(cart) { try { const mynewcart = new Cart(null); mynewcart.idapp = cart.idapp || 0; mynewcart.items = cart.items; mynewcart.department = cart.department; mynewcart.userId = cart.userId || ""; mynewcart.modify_at = new Date(); mynewcart.note_ordine_gas = ''; return mynewcart; } catch (e) { console.log('Error', e); return null; } } isAvailableByOrder(order) { if (order && order.product) { return (order.product.quantityAvailable > 0) } return false; } isInPreorderByOrder(order) { if (order && order.product) { return (order.product.bookableAvailableQty > 0) } return false; } isSameStorehouse(itemorder) { try { if (this.items.length > 0) { const mystorehouse = this.items[0].order.idStorehouse return (mystorehouse ? mystorehouse._id.toString() === itemorder.idStorehouse : true); } else { return true; } } catch (e) { return false; } } async addqty(itemorder) { const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id) if (!!myitem) { let stepmin = myitem.order.product.minStepQty; let step = stepmin; if (this.isAvailableByOrder(myitem.order)) { if (myitem.order.quantity === 0) step = myitem.order.product.minBuyQty ?? stepmin else if (myitem.order.quantity >= 10) step = stepmin < 2 ? 2 : stepmin else if (myitem.order.quantity >= 20) step = stepmin < 5 ? 5 : stepmin myitem.order.quantity += step; } else { if (myitem.order.quantitypreordered === 0) step = myitem.order.product.minBuyQty ?? stepmin else if (myitem.order.quantitypreordered >= 10) step = stepmin < 2 ? 2 : stepmin else if (myitem.order.quantitypreordered >= 20) step = stepmin < 5 ? 5 : stepmin myitem.order.quantitypreordered += step; } myitem.order.modify_at = new Date(); myitem.order = Order.updateTotals(myitem.order); this.updatecarttotals(false); await this.updateExtraOrder(); await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false }); return myitem.order; } } qtaNextSub(myorder, myproduct) { let step = myproduct.minStepQty let minqta = myproduct.minBuyQty if (myproduct.quantityAvailable > 0) { if (myorder.quantity === minqta) step = minqta else { if ((myorder.quantity - step) < 0) step = myorder.quantity - step } } else { if (myorder.quantitypreordered === minqta) step = minqta } return step } async subqty(itemorder) { try { const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id) if (!!myitem) { let step = this.qtaNextSub(myitem.order, myitem.order.product); if (myitem.order.quantitypreordered - step >= 0) { myitem.order.quantitypreordered -= step; } else { if (myitem.order.quantity - step >= 0) { myitem.order.quantity -= step; } } myitem.order = Order.updateTotals(myitem.order); this.updatecarttotals(false); await this.updateExtraOrder(); await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false }); return myitem.order; } } catch (e) { console.error('Err: ', e); } } async addItem(itemorder) { // this.items.push(itemorder); let ind = this.items.length; this.items[ind] = {}; this.items[ind].order = itemorder; this.items[ind].order = Order.updateTotals(this.items[ind].order); this.updatecarttotals(false); await this.updateExtraOrder(); return ind; } async removeItem(orderId) { // this.items.push(itemorder); this.items = this.items.filter(item => item.order._id.toString() !== orderId.toString()); this.updatecarttotals(false); await this.updateExtraOrder(); } generateModel() { try { let newCart = new cartModel({ idapp: this.idapp, items: this.generateArray(), totalQty: this.totalQty, totalPriceCalc: this.totalPriceCalc, totalPrice: this.totalPrice, userId: this.userId, department: this.department, note: this.note, note_ordine_gas: this.note_ordine_gas, modify_at: this.modify_at }) return newCart } catch (e) { console.error('Err', e); } return null; } updatecarttotals(updatecalcprice) { try { this.totalQty = 0; this.totalPrice = 0; this.totalPriceCalc = 0; for (const rec in this.items) { let mypricecalc = 0; let order = this.items[rec].order; if (!order) { order = this.items[rec]; } order.TotalPriceProductCalc = 0; if (updatecalcprice) { order.TotalPriceProduct = 0; } this.totalQty += order.quantity + order.quantitypreordered; // Calcolo Sconto let sconti_da_applicare = []; if (order.scontisticas) { let qtadascontare = order.quantity + order.quantitypreordered let qtanonscontata = 0 while (qtadascontare > 0) { let scontoapplicato = null for (const sconto of order.scontisticas.filter((rec) => !rec.cumulativo)) { if (qtadascontare >= sconto.qta) { scontoapplicato = sconto scontoapplicato.qtadascontare = sconto.qta } } if (scontoapplicato && scontoapplicato.qtadascontare > 0) { sconti_da_applicare.push(scontoapplicato) qtadascontare -= scontoapplicato.qtadascontare } else { qtanonscontata = qtadascontare qtadascontare = 0 } } /*for (const sconto of order.scontisticas.filter((rec) => rec.cumulativo)) { if ((sconto.qta % order.quantity) === 0) { sconti_da_applicare.push(sconto) } }*/ if (sconti_da_applicare.length > 0) { for (const sconto of sconti_da_applicare) { if (sconto.perc_sconto > 0) { mypricecalc += (sconto.qtadascontare * order.price) * (1 - (sconto.perc_sconto / 100)) } else { mypricecalc += sconto.price } } } if (qtanonscontata > 0) { mypricecalc += order.price * qtanonscontata; } } else { mypricecalc = (order.price * order.quantity) + (order.price * order.quantitypreordered); } // Aggiorna Totali order.TotalPriceProductCalc += mypricecalc; if (updatecalcprice) { order.TotalPriceProduct += mypricecalc; order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2)); } // Qui lo calcolo sempre, anche se lo cambio manualmente this.totalPriceCalc += mypricecalc; this.totalPrice += order.TotalPriceProduct; } this.totalPrice = parseFloat(this.totalPrice.toFixed(2)) this.totalPriceCalc = parseFloat(this.totalPriceCalc.toFixed(2)) } catch (e) { console.error('Err: ', e); } } async updateExtraOrder() { try { let arrGas = []; const precnoteordgas = this.note_ordine_gas this.note_ordine_gas = ''; for (const rec in this.items) { let order = this.items[rec].order; if (!order) { order = this.items[rec]; } // Prendo la nota valida e la metto visibile sul Carrello ! if (order.idGasordine) { const recGas = await Gasordine.findOne({ _id: order.idGasordine }).lean(); if (recGas) { if (recGas.note_ordine_gas) { if (!arrGas.includes(recGas._id.toString())) { if (this.note_ordine_gas) this.note_ordine_gas += '
' this.note_ordine_gas += '' + recGas.name + '' + ':
' + recGas.note_ordine_gas; arrGas.push(recGas._id.toString()); } } } } } } catch (e) { console.error('Err:', e); } } generateArray() { let arr = []; for (let id in this.items) { arr.push(this.items[id]) } return arr; } } module.exports = Cart