Files
freeplanet_serverside/src/server/modules/Cart.js
Surya Paolo 5668c620da - Sistemato link pdf che ogni volta che si aggiorna prendeva il PDF dalla cache...
- Raccolta Cataloghi, procedura che li AUTO genera in automatico.
2025-06-13 17:46:03 +02:00

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;