362 lines
10 KiB
JavaScript
Executable File
362 lines
10 KiB
JavaScript
Executable File
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');
|
|
const OrderClass = require('../modules/OrderClass');
|
|
|
|
const Scontistica = require('../models/scontistica');
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
async updatecarttotals(updateCalcPrice = true) {
|
|
try {
|
|
this.totalQty = 0;
|
|
this.totalPrice = 0;
|
|
this.totalPriceCalc = 0;
|
|
this.totalPriceIntero = 0;
|
|
|
|
for (const key in this.items) {
|
|
const item = this.items[key];
|
|
const order = item.order || item;
|
|
|
|
await this.updateOrderTotals(order, updateCalcPrice);
|
|
}
|
|
|
|
this.totalPrice = parseFloat(this.totalPrice.toFixed(2));
|
|
this.totalPriceCalc = parseFloat(this.totalPriceCalc.toFixed(2));
|
|
this.totalPriceIntero = parseFloat(this.totalPriceIntero.toFixed(2));
|
|
} catch (e) {
|
|
console.error("Errore durante l'aggiornamento del carrello:", e);
|
|
}
|
|
}
|
|
|
|
async init() {
|
|
await this.updatecarttotals(false);
|
|
}
|
|
|
|
initializeFromOrder(order) {
|
|
this.idapp = order.idapp || 0;
|
|
this.userId = order.userId || '';
|
|
this.items[order._id] = order;
|
|
}
|
|
static async constructByCart(cart) {
|
|
try {
|
|
const mynewcart = new Cart(null);
|
|
await mynewcart.init();
|
|
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 = '';
|
|
mynewcart.codice_sconto = cart.codice_sconto;
|
|
mynewcart.descr_sconto = cart.descr_sconto;
|
|
|
|
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 || 1;
|
|
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 = await Order.updateTotals(myitem.order, this.codice_sconto);
|
|
|
|
await this.updatecarttotals(false);
|
|
await this.updateExtraOrder();
|
|
await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false });
|
|
return myitem.order;
|
|
}
|
|
}
|
|
|
|
qtaNextSub(myorder, myproduct) {
|
|
try {
|
|
let step = myproduct.minStepQty || 1;
|
|
let minqta = myproduct.minBuyQty || 1;
|
|
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;
|
|
}
|
|
step = myorder.quantity - stepΩ;
|
|
}
|
|
return step;
|
|
} catch (e) {
|
|
console.error('Error in qtaNextSub: ', e);
|
|
return 0; // default step value in case of error
|
|
}
|
|
}
|
|
|
|
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 = await Order.updateTotals(myitem.order, this.codice_sconto);
|
|
await 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 = await Order.updateTotals(this.items[ind].order, this.codice_sconto);
|
|
await 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());
|
|
await this.updatecarttotals(false);
|
|
await this.updateExtraOrder();
|
|
}
|
|
|
|
generateModel() {
|
|
try {
|
|
let newCart = new cartModel({
|
|
idapp: this.idapp,
|
|
items: this.generateArray(),
|
|
totalQty: this.totalQty,
|
|
totalPriceCalc: this.totalPriceCalc,
|
|
totalPriceIntero: this.totalPriceIntero,
|
|
totalPrice: this.totalPrice,
|
|
userId: this.userId,
|
|
department: this.department,
|
|
note: this.note,
|
|
codice_sconto: this.codice_sconto,
|
|
descr_sconto: this.descr_sconto,
|
|
note_ordine_gas: this.note_ordine_gas,
|
|
modify_at: this.modify_at,
|
|
});
|
|
return newCart;
|
|
} catch (e) {
|
|
console.error('Err', e);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async updateOrderTotals(order, updateCalcPrice) {
|
|
order.TotalPriceProductCalc = 0;
|
|
|
|
// PROVO A METTERE SEMPRE CHE MI RICALCOLA IL PREZZO !
|
|
// updateCalcPrice = true;
|
|
|
|
if (updateCalcPrice) {
|
|
order.TotalPriceProduct = 0;
|
|
}
|
|
|
|
const qty = order.quantity + order.quantitypreordered;
|
|
this.totalQty += qty;
|
|
|
|
const recscontisticheTrovate = await Cart.getRecSconto(this.idapp, this.codice_sconto, true);
|
|
|
|
const scontiDaUsare = recscontisticheTrovate?.length ? recscontisticheTrovate : order.scontisticas || [];
|
|
const priceCalc = this.calcolaPrezzoScontato(order, qty, scontiDaUsare);
|
|
const priceintero = this.calcolaPrezzoScontato(order, qty, []);
|
|
|
|
order.TotalPriceProductCalc += priceCalc;
|
|
|
|
if (updateCalcPrice) {
|
|
order.TotalPriceProduct += priceCalc;
|
|
order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2));
|
|
}
|
|
|
|
this.totalPrice += order.TotalPriceProduct;
|
|
this.totalPriceCalc += priceCalc;
|
|
this.totalPriceIntero += priceintero;
|
|
|
|
// if (updateCalcPrice) {
|
|
// Aggiorna anche l'ordine associato
|
|
await Order.findOneAndUpdate({ _id: order._id }, { $set: order }, { new: false });
|
|
// }
|
|
}
|
|
|
|
calcolaPrezzoScontato(order, qtyTotale, sconti = []) {
|
|
if (!sconti || sconti.length === 0) {
|
|
return order.price * qtyTotale;
|
|
}
|
|
|
|
const { sconti_da_applicare, qtanonscontata } = OrderClass.applyNonCumulativeDiscounts(order, sconti);
|
|
|
|
const prezzoTotale = OrderClass.calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata);
|
|
|
|
return prezzoTotale;
|
|
}
|
|
|
|
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 += '<br>';
|
|
|
|
this.note_ordine_gas += '<strong>' + recGas.name + '</strong>' + ':<br>' + 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;
|
|
}
|
|
|
|
static async getRecSconto(idapp, codice_sconto, soloAttivi) {
|
|
const condSconto = { $regex: new RegExp(`^${codice_sconto}$`, 'i') };
|
|
const query = {
|
|
idapp: idapp,
|
|
code: condSconto,
|
|
applica: shared_consts.SCONTI_APPLICA.A_TUTTI,
|
|
};
|
|
|
|
if (soloAttivi) {
|
|
query.attivo = true;
|
|
}
|
|
|
|
const recscontisticheTrovate = await Scontistica.find(query).lean();
|
|
|
|
return recscontisticheTrovate;
|
|
}
|
|
|
|
async updateCartIntoDB() {
|
|
const result = await cartModel.updateCartByUserId(this.userId, {
|
|
items: this.items,
|
|
totalQty: this.totalQty,
|
|
totalPrice: this.totalPrice,
|
|
totalPriceCalc: this.totalPriceCalc,
|
|
totalPriceIntero: this.totalPriceIntero,
|
|
userId: this.userId,
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
async aggiornaCarrello() {
|
|
try {
|
|
// Rifai i calcoli !
|
|
await this.updatecarttotals(true);
|
|
|
|
await this.updateExtraOrder();
|
|
|
|
// Aggiorna i calcoli sul DB:
|
|
const mycart = await this.updateCartIntoDB();
|
|
|
|
// ritorna il carrello aggiornato !
|
|
return await cartModel.getCartCompletoByCartId(mycart._id, this.idapp);
|
|
} catch (e) {
|
|
console.error("Errore durante l'aggiornamento del carrello:", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Cart;
|