From d1d4b73da08c1d8962bc555588fbd6ea66be8b6f Mon Sep 17 00:00:00 2001 From: Surya Paolo Date: Mon, 9 Jun 2025 09:48:40 +0200 Subject: [PATCH] - Esporta Lista Carrello (Totale) - Sconto Applicato --- src/server/models/cart.js | 6 + src/server/models/order.js | 508 +++++++++++++++--------------- src/server/models/orderscart.js | 9 +- src/server/models/scontistica.js | 3 + src/server/modules/Cart.js | 291 +++++++++-------- src/server/router/cart_router.js | 389 +++++++++++++---------- src/server/tools/shared_nodejs.js | 7 +- 7 files changed, 646 insertions(+), 567 deletions(-) diff --git a/src/server/models/cart.js b/src/server/models/cart.js index cb10e2d..688740e 100755 --- a/src/server/models/cart.js +++ b/src/server/models/cart.js @@ -30,6 +30,9 @@ const CartSchema = new Schema({ note: { type: String, }, + codice_sconto: { + type: String, + }, note_ordine_gas: { type: String, }, @@ -116,6 +119,7 @@ module.exports.updateCartByUserId = async function (userId, newCart) { } else { // Se il carrello non esiste, crea un nuovo documento const createdCart = new Cart(newCart); + await createdCart.init(); const savedCart = await createdCart.save(); return savedCart; // Restituisce il carrello creato } @@ -133,6 +137,7 @@ module.exports.updateCartByCartId = async function (cartId, newCart) { const totalPrice = newCart.totalPrice; const totalPriceCalc = newCart.totalPriceCalc; const note = newCart.note; + const codice_sconto = newCart.codice_sconto; const note_ordine_gas = newCart.note_ordine_gas; const modify_at = new Date(); @@ -144,6 +149,7 @@ module.exports.updateCartByCartId = async function (cartId, newCart) { totalPriceCalc, totalQty, note, + codice_sconto, note_ordine_gas, modify_at: new Date(), }, diff --git a/src/server/models/order.js b/src/server/models/order.js index d5a8729..aa60f5d 100755 --- a/src/server/models/order.js +++ b/src/server/models/order.js @@ -1,19 +1,20 @@ - -const mongoose = require('mongoose').set('debug', false) +const mongoose = require('mongoose').set('debug', false); const Schema = mongoose.Schema; const shared_consts = require('../tools/shared_nodejs'); const { ObjectId } = require('mongodb'); +const Scontistica = require('../models/scontistica'); + mongoose.Promise = global.Promise; -mongoose.level = "F"; +mongoose.level = 'F'; const fs = require('fs'); // 👈 Usa il modulo promises // Resolving error Unknown modifier: $pushAll -mongoose.plugin(schema => { - schema.options.usePushEach = true +mongoose.plugin((schema) => { + schema.options.usePushEach = true; }); const orderSchema = new Schema({ @@ -22,7 +23,8 @@ const orderSchema = new Schema({ }, userId: { type: Schema.Types.ObjectId, ref: 'User' }, status: { - type: Number, index: true + type: Number, + index: true, }, idProduct: { type: Schema.Types.ObjectId, ref: 'Product', index: true }, idProducer: { type: Schema.Types.ObjectId, ref: 'Producer' }, @@ -35,13 +37,13 @@ const orderSchema = new Schema({ default: 0, }, after_price: { - type: String + type: String, }, color: { - type: String + type: String, }, size: { - type: String + type: String, }, quantity: { type: Number, @@ -62,83 +64,89 @@ const orderSchema = new Schema({ type: Number, default: 0, }, - confermato: { // e quindi è stato tolto dal magazzino (aggiornando il campo stockQty) + confermato: { + // e quindi è stato tolto dal magazzino (aggiornando il campo stockQty) type: Boolean, default: false, }, date_confermato: { - type: Date + type: Date, }, pagato: { type: Boolean, default: false, }, date_pagato: { - type: Date + type: Date, }, consegnato: { type: Boolean, default: false, }, date_consegnato: { - type: Date + type: Date, }, spedito: { type: Boolean, default: false, }, date_spedito: { - type: Date + type: Date, }, ricevuto: { type: Boolean, default: false, }, date_ricevuto: { - type: Date + type: Date, }, weight: { - type: Number + type: Number, }, unit: { - type: Number + type: Number, }, stars: { - type: Number + type: Number, }, date_created: { - type: Date + type: Date, }, date_checkout: { - type: Date + type: Date, }, date_payment: { - type: Date + type: Date, }, date_shipping: { - type: Date + type: Date, }, date_delivered: { - type: Date + type: Date, }, note: { - type: String + type: String, + }, + codice_sconto: { + type: String, }, modify_at: { type: Date, - index: true + index: true, }, }); -var Order = module.exports = mongoose.model('Order', orderSchema); - -module.exports.createIndexes() - .then(() => { }) - .catch((err) => { throw err; }); +var Order = (module.exports = mongoose.model('Order', orderSchema)); +module.exports + .createIndexes() + .then(() => {}) + .catch((err) => { + throw err; + }); module.exports.getFieldsForSearch = function () { - return [] + return []; }; module.exports.executeQueryTable = function (idapp, params) { @@ -149,7 +157,6 @@ module.exports.executeQueryTable = function (idapp, params) { }; module.exports.findAllIdApp = async function (idapp) { - const query = [ { $match: { idapp } }, { @@ -157,16 +164,16 @@ module.exports.findAllIdApp = async function (idapp) { from: 'products', localField: 'idProduct', foreignField: '_id', - as: 'product' - } + as: 'product', + }, }, { $lookup: { from: 'productinfos', localField: 'product.idProduct', foreignField: '_id', - as: 'product.productInfo' - } + as: 'product.productInfo', + }, }, { $unwind: { @@ -179,24 +186,24 @@ module.exports.findAllIdApp = async function (idapp) { from: 'producers', localField: 'product.idProducer', foreignField: '_id', - as: 'producer' - } + as: 'producer', + }, }, { $lookup: { from: 'providers', localField: 'product.idProvider', foreignField: '_id', - as: 'provider' - } + as: 'provider', + }, }, { $lookup: { from: 'gasordines', localField: 'idGasordine', foreignField: '_id', - as: 'gasordine' - } + as: 'gasordine', + }, }, { $unwind: { @@ -206,19 +213,16 @@ module.exports.findAllIdApp = async function (idapp) { }, { $match: { - $or: [ - { 'gasordine': { $exists: false } }, - { 'gasordine.active': true } - ] - } + $or: [{ gasordine: { $exists: false } }, { 'gasordine.active': true }], + }, }, { $lookup: { from: 'scontisticas', localField: 'product.idScontisticas', foreignField: '_id', - as: 'scontistica' - } + as: 'scontistica', + }, }, { $unwind: { @@ -238,144 +242,160 @@ module.exports.findAllIdApp = async function (idapp) { preserveNullAndEmptyArrays: true, }, }, - ]; - return await Order.aggregate(query) - + return await Order.aggregate(query); }; module.exports.getAllOrders = function (query, sort, callback) { - Order.find(query, null, sort, callback) -} + Order.find(query, null, sort, callback); +}; module.exports.getOrderByUserId = function (userId, sort, callback) { - Order.find({ userId }, null, sort, callback) -} - + Order.find({ userId }, null, sort, callback); +}; module.exports.getOrderByID = function (id, callback) { Order.findById(id, callback); -} +}; module.exports.createOrder = async function (order) { - try { if (order.idGasordine === '') { order.idGasordine = undefined; } - Order.updateTotals(order); - return await Order.create(order) - .then((ris) => { - if (!!ris) - return ris._id; - return null; - }); + await Order.updateTotals(order); + return await Order.create(order).then((ris) => { + if (!!ris) return ris._id; + return null; + }); } catch (e) { console.error('err', e); } -} +}; module.exports.updateStatusOrders = async function (arrOrders, status) { - for (const order of arrOrders) { let ret = await Order.updateOne({ _id: order.order._id }, { $set: { status } }); } - -} +}; module.exports.updateStatusOrdersElements = async function (arrOrders, myelements) { - for (const order of arrOrders) { const ret = await Order.findOneAndUpdate({ _id: order.order._id }, { $set: myelements }); } - -} +}; module.exports.updateOrderByParams = async function (idOrder, paramstoupdate) { - const ris = await Order.findOneAndUpdate({ _id: idOrder }, { $set: paramstoupdate }); let myorder = await Order.findOne({ _id: idOrder }).lean(); if (paramstoupdate && !paramstoupdate.hasOwnProperty('TotalPriceProduct')) { - this.updateTotals(myorder); + await this.updateTotals(myorder); await Order.findOneAndUpdate({ _id: idOrder }, { $set: myorder }); } return myorder; +}; + +function initOrderTotals(order) { + order.TotalPriceProduct = 0; + order.TotalPriceProductCalc = 0; + order.modify_at = new Date(); } -module.exports.updateTotals = function (order) { +function getNonCumulativeDiscounts(discounts) { + return discounts.filter((rec) => !rec.cumulativo); +} - try { - if (!order) { - return; +function applyNonCumulativeDiscounts(order, discounts) { + let qtadascontare = order.quantity + order.quantitypreordered; + let qtanonscontata = 0; + let sconti_da_applicare = []; + + while (qtadascontare > 0) { + let scontoapplicato = null; + for (const sconto of getNonCumulativeDiscounts(discounts)) { + if (qtadascontare >= sconto.qta) { + scontoapplicato = { ...sconto, qtadascontare: sconto.qta }; + } } - - let mypricecalc = 0; - order.TotalPriceProduct = 0; - order.TotalPriceProductCalc = 0; - order.modify_at = new Date(); - - // 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; - } - + if (scontoapplicato && scontoapplicato.qtadascontare > 0) { + sconti_da_applicare.push(scontoapplicato); + qtadascontare -= scontoapplicato.qtadascontare; } else { - mypricecalc = (order.price * order.quantity) + (order.price * order.quantitypreordered); + qtanonscontata = qtadascontare; + qtadascontare = 0; + } + } + + return { sconti_da_applicare, qtanonscontata }; +} + +function calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata) { + let total = 0; + + for (const sconto of sconti_da_applicare) { + if (sconto.perc_sconto > 0) { + total += sconto.qtadascontare * order.price * (1 - sconto.perc_sconto / 100); + } else { + total += sconto.price; + } + } + + if (qtanonscontata > 0) { + total += order.price * qtanonscontata; + } + + return total; +} + +function calculateFullPrice(order) { + return order.price * order.quantity + order.price * order.quantitypreordered; +} + +module.exports.updateTotals = async function (order) { + try { + if (!order) return; + + initOrderTotals(order); + + let total = 0; + + let scontoapplicato = false; + + let recscontisticheTrovate = []; + + if (order?.codice_sconto) { + recscontisticheTrovate = await Scontistica.find({ + idapp: order.idapp, + code: order?.codice_sconto?.toUpperCase(), + applica: shared_consts.SCONTI_APPLICA.A_TUTTI, + }).lean(); } - order.TotalPriceProductCalc += mypricecalc; - order.TotalPriceProduct += mypricecalc; + // Se ha inserito una scontistica che esiste... + if (recscontisticheTrovate && recscontisticheTrovate.length > 0) { + const { sconti_da_applicare, qtanonscontata } = applyNonCumulativeDiscounts(order, recscontisticheTrovate); + total = calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata); + } else if (order.scontisticas && order.scontisticas.length > 0) { + const { sconti_da_applicare, qtanonscontata } = applyNonCumulativeDiscounts(order, order.scontisticas); + total = calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata); + } else { + total = calculateFullPrice(order); + } + + order.TotalPriceProductCalc += total; + order.TotalPriceProduct += total; order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2)); return order; - } catch (e) { console.error('Err:', e); } -} +}; module.exports.getTotalOrderById = async function (id) { const query = [ @@ -385,8 +405,8 @@ module.exports.getTotalOrderById = async function (id) { from: 'products', localField: 'idProduct', foreignField: '_id', - as: 'product' - } + as: 'product', + }, }, { $unwind: { @@ -399,8 +419,8 @@ module.exports.getTotalOrderById = async function (id) { from: 'productinfos', localField: 'product.idProductInfo', foreignField: '_id', - as: 'product.productInfo' - } + as: 'product.productInfo', + }, }, { $unwind: { @@ -413,8 +433,8 @@ module.exports.getTotalOrderById = async function (id) { from: 'producers', localField: 'product.idProducer', foreignField: '_id', - as: 'producer' - } + as: 'producer', + }, }, { $unwind: { @@ -427,8 +447,8 @@ module.exports.getTotalOrderById = async function (id) { from: 'storehouses', localField: 'idStorehouse', foreignField: '_id', - as: 'storehouse' - } + as: 'storehouse', + }, }, { $unwind: { @@ -441,8 +461,8 @@ module.exports.getTotalOrderById = async function (id) { from: 'providers', localField: 'product.idProvider', foreignField: '_id', - as: 'provider' - } + as: 'provider', + }, }, { $unwind: { @@ -455,8 +475,8 @@ module.exports.getTotalOrderById = async function (id) { from: 'gasordines', localField: 'idGasordine', foreignField: '_id', - as: 'gasordine' - } + as: 'gasordine', + }, }, { $unwind: { @@ -466,19 +486,16 @@ module.exports.getTotalOrderById = async function (id) { }, { $match: { - $or: [ - { 'gasordine': { $exists: false } }, - { 'gasordine.active': true } - ] - } + $or: [{ gasordine: { $exists: false } }, { 'gasordine.active': true }], + }, }, { $lookup: { from: 'scontisticas', localField: 'product.idScontisticas', foreignField: '_id', - as: 'scontisticas' - } + as: 'scontisticas', + }, }, { $lookup: { @@ -493,32 +510,34 @@ module.exports.getTotalOrderById = async function (id) { { $or: [ { - $eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] + $eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT], }, { - $and: [{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] }, - { - $gt: [ - '$modify_at', - { $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60 - ] - }] - } - ] - } - ] - } + $and: [ + { $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] }, + { + $gt: [ + '$modify_at', + { $subtract: [new Date(), 60 * 60 * 1000] }, // 1 hour in milliseconds 60 * 60 + ], + }, + ], + }, + ], + }, + ], + }, }, }, { $group: { _id: null, totalQty: { $sum: '$quantity' }, - } - } + }, + }, ], - as: 'productOrders' - } + as: 'productOrders', + }, }, { $lookup: { @@ -533,32 +552,34 @@ module.exports.getTotalOrderById = async function (id) { { $or: [ { - $eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] + $eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT], }, { - $and: [{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] }, - { - $gt: [ - '$modify_at', - { $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60 - ] - }] - } - ] - } - ] - } - } + $and: [ + { $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] }, + { + $gt: [ + '$modify_at', + { $subtract: [new Date(), 60 * 60 * 1000] }, // 1 hour in milliseconds 60 * 60 + ], + }, + ], + }, + ], + }, + ], + }, + }, }, { $group: { _id: null, - totalQtyPreordered: { $sum: '$quantitypreordered' } - } - } + totalQtyPreordered: { $sum: '$quantitypreordered' }, + }, + }, ], - as: 'productPreOrders' - } + as: 'productPreOrders', + }, }, { $addFields: { @@ -568,11 +589,11 @@ module.exports.getTotalOrderById = async function (id) { $cond: { if: { $isArray: '$productOrders' }, then: { $arrayElemAt: ['$productOrders.totalQty', 0] }, - else: 0 - } + else: 0, + }, }, - 0 - ] + 0, + ], }, 'product.QuantitaPrenotateInAttesa': { $ifNull: [ @@ -580,36 +601,35 @@ module.exports.getTotalOrderById = async function (id) { $cond: { if: { $isArray: '$productPreOrders' }, then: { $arrayElemAt: ['$productPreOrders.totalQtyPreordered', 0] }, - else: 0 - } + else: 0, + }, }, - 0 - ] + 0, + ], }, }, }, { $addFields: { 'product.quantityAvailable': { - $subtract: ["$product.stockQty", "$product.QuantitaOrdinateInAttesa"], + $subtract: ['$product.stockQty', '$product.QuantitaOrdinateInAttesa'], }, 'product.bookableAvailableQty': { - $subtract: ["$product.maxbookableGASQty", "$product.QuantitaPrenotateInAttesa"], - } - } + $subtract: ['$product.maxbookableGASQty', '$product.QuantitaPrenotateInAttesa'], + }, + }, }, { - $unset: 'productOrders' + $unset: 'productOrders', }, { - $unset: 'productPreOrders' + $unset: 'productPreOrders', }, - ]; const ris = await Order.aggregate(query); return ris; -} +}; module.exports.RemoveDeletedOrdersInOrderscart = async function () { try { @@ -620,11 +640,11 @@ module.exports.RemoveDeletedOrdersInOrderscart = async function () { for (const rec of arrorders) { let recordercart = await OrdersCart.getOrdersCartById(rec._id); - let arrord = [] + let arrord = []; let cambiare = false; for (const recOrd of recordercart.items) { if (recOrd.order) { - arrord.push(recOrd) + arrord.push(recOrd); } else { cambiare = true; } @@ -647,18 +667,14 @@ module.exports.RemoveDeletedOrdersInOrderscart = async function () { await Order.findOneAndDelete({ _id: ord._id }); } }) - .catch(err => console.error(err)); + .catch((err) => console.error(err)); } - - } catch (e) { console.error('Err', e); } - }; module.exports.GeneraCSVOrdineProdotti = async function () { - const myidGasordine = '65c2a8cc379ee4f57e865ee7'; const myquery = [ @@ -668,8 +684,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () { from: 'products', localField: 'idProduct', foreignField: '_id', - as: 'product' - } + as: 'product', + }, }, { $unwind: { @@ -682,8 +698,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () { from: 'productinfos', localField: 'product.idProductInfo', foreignField: '_id', - as: 'productInfo' - } + as: 'productInfo', + }, }, { $unwind: { @@ -695,8 +711,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () { from: 'gasordines', localField: 'idGasordine', foreignField: '_id', - as: 'gasordine' - } + as: 'gasordine', + }, }, { $unwind: { @@ -707,67 +723,57 @@ module.exports.GeneraCSVOrdineProdotti = async function () { { $match: { $or: [ - { 'gasordine.active': true }, // Include documents where gasordines.active is true - { 'gasordine': { $exists: false } } // Include documents where gasordines array doesn't exist - ] - } + { 'gasordine.active': true }, // Include documents where gasordines.active is true + { gasordine: { $exists: false } }, // Include documents where gasordines array doesn't exist + ], + }, }, { $match: { - $or: [ - { quantity: { $gt: 0 }, }, - { quantitypreordered: { $gt: 0 }, } - ] - } + $or: [{ quantity: { $gt: 0 } }, { quantitypreordered: { $gt: 0 } }], + }, }, { $group: { - _id: "$product._id", - name: { $first: "$productInfo.name" }, - weight: { $first: "$productInfo.weight" }, - price_acquistato: { $first: "$product.price_acquistato" }, - totalQuantity: { $sum: { $add: ["$quantity", "$quantitypreordered"] } }, - totalPrice_acquistato: { $sum: { $multiply: ["$product.price_acquistato", { $add: ["$quantity", "$quantitypreordered"] }] } }, - count: { $sum: 1 } - } + _id: '$product._id', + name: { $first: '$productInfo.name' }, + weight: { $first: '$productInfo.weight' }, + price_acquistato: { $first: '$product.price_acquistato' }, + totalQuantity: { $sum: { $add: ['$quantity', '$quantitypreordered'] } }, + totalPrice_acquistato: { + $sum: { $multiply: ['$product.price_acquistato', { $add: ['$quantity', '$quantitypreordered'] }] }, + }, + count: { $sum: 1 }, + }, }, { $sort: { - name: 1 // Sort in ascending order based on the "date_created" field + name: 1, // Sort in ascending order based on the "date_created" field }, - } + }, ]; let myorderscart = await Order.aggregate(myquery); - console.log(myorderscart) + console.log(myorderscart); return generateCSV(myorderscart, 'outout.csv'); - -} +}; function generateCSV(data, outputPath) { const headers = ['Num', 'Nome', 'Peso', 'Prezzo', 'Quantita', 'Totale', 'Ordini']; - const rows = data.map(item => { + const rows = data.map((item) => { const formattedPrice = item.price_acquistato.toString().replace(/\./g, ','); // Converti "." in "," const total = item.totalPrice_acquistato.toString().replace(/\./g, ','); // Converti "." in "," - return [ - 0, - `"${item.name}"`, - item.weight, - formattedPrice, - item.totalQuantity, - total, - item.count - ]; + return [0, `"${item.name}"`, item.weight, formattedPrice, item.totalQuantity, total, item.count]; }); rows.unshift(headers); - const csvData = rows.map(row => row.join('|')); + const csvData = rows.map((row) => row.join('|')); fs.writeFile(outputPath, csvData.join('\n'), (err) => { if (err) { @@ -778,8 +784,6 @@ function generateCSV(data, outputPath) { }); } - - // const Order = mongoose.model('Order', OrderSchema); // module.exports = { Order }; diff --git a/src/server/models/orderscart.js b/src/server/models/orderscart.js index 39492c0..eda9cf7 100755 --- a/src/server/models/orderscart.js +++ b/src/server/models/orderscart.js @@ -91,6 +91,9 @@ const OrdersCartSchema = new Schema({ note: { type: String }, + codice_sconto: { + type: String + }, note_per_gestore: { type: String }, @@ -573,6 +576,7 @@ module.exports.updateOrdersCartById = async function(id, newOrdersCart, callback numorder: newOrdersCart.numorder, numord_pers: newOrdersCart.numord_pers, note: newOrdersCart.note, + codice_sconto: newOrdersCart.codice_sconto, modify_at: new Date(), } }, @@ -1076,9 +1080,9 @@ module.exports.updateOrdersCartTotals = async function (idOrdersCart, update) { let orderscart = await OrdersCart.getOrdersCartById(idOrdersCart); if (orderscart) { - let newOrdersCart = CartClass.constructByCart(orderscart); + let newOrdersCart = await CartClass.constructByCart(orderscart); - newOrdersCart.updatecarttotals(false); + await newOrdersCart.updatecarttotals(false); await newOrdersCart.updateExtraOrder(); if (update) { @@ -1088,6 +1092,7 @@ module.exports.updateOrdersCartTotals = async function (idOrdersCart, update) { totalPriceCalc: newOrdersCart.totalPriceCalc, totalQty: newOrdersCart.totalQty, note: newOrdersCart.note, + codice_sconto: newOrdersCart.codice_sconto, modify_at: new Date(), }, } diff --git a/src/server/models/scontistica.js b/src/server/models/scontistica.js index 40c0322..aa8ea53 100755 --- a/src/server/models/scontistica.js +++ b/src/server/models/scontistica.js @@ -31,6 +31,9 @@ const scontisticaSchema = new Schema({ price: { type: Number, }, + applica: { + type: Number, + }, comulativo: { type: Boolean, default: false, diff --git a/src/server/modules/Cart.js b/src/server/modules/Cart.js index 962e9a1..6c4dec2 100755 --- a/src/server/modules/Cart.js +++ b/src/server/modules/Cart.js @@ -1,5 +1,5 @@ const shared_consts = require('../tools/shared_nodejs'); -const cartModel = require('../models/cart') +const cartModel = require('../models/cart'); const { ObjectId } = require('mongodb'); @@ -7,6 +7,8 @@ const Gasordine = require('../models/gasordine'); const Order = require('../models/order'); +const Scontistica = require('../models/scontistica'); + class Cart { constructor(order, arrorders) { this.modify_at = new Date(); @@ -16,26 +18,50 @@ class Cart { this.initializeFromOrder(order); } else if (!!arrorders) { for (const ord of arrorders) { - this.items.push(ord) + this.items.push(ord); } } - this.updatecarttotals(false); + } + async updatecarttotals(updateCalcPrice = true) { + try { + this.totalQty = 0; + this.totalPrice = 0; + this.totalPriceCalc = 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)); + } 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.userId = order.userId || ''; this.items[order._id] = order; } - static constructByCart(cart) { + 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.userId = cart.userId || ''; mynewcart.modify_at = new Date(); mynewcart.note_ordine_gas = ''; + mynewcart.codice_sconto = cart.codice_sconto; return mynewcart; } catch (e) { @@ -46,14 +72,14 @@ class Cart { isAvailableByOrder(order) { if (order && order.product) { - return (order.product.quantityAvailable > 0) + return order.product.quantityAvailable > 0; } return false; } isInPreorderByOrder(order) { if (order && order.product) { - return (order.product.bookableAvailableQty > 0) + return order.product.bookableAvailableQty > 0; } return false; } @@ -61,48 +87,40 @@ class Cart { isSameStorehouse(itemorder) { try { if (this.items.length > 0) { - const mystorehouse = this.items[0].order.idStorehouse - return (mystorehouse ? mystorehouse._id.toString() === itemorder.idStorehouse : true); + 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) + 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 + 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 + 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); + myitem.order = await Order.updateTotals(myitem.order); - this.updatecarttotals(false); + await this.updatecarttotals(false); await this.updateExtraOrder(); await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false }); return myitem.order; @@ -110,27 +128,33 @@ class Cart { } 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 + 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Ω; } - } else { - if (myorder.quantitypreordered === minqta) - step = minqta + return step; + } catch (e) { + console.error('Error in qtaNextSub: ', e); + return 0; // default step value in case of error } - - return step } - async subqty(itemorder) { try { - const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id) + 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) { @@ -140,8 +164,8 @@ class Cart { myitem.order.quantity -= step; } } - myitem.order = Order.updateTotals(myitem.order); - this.updatecarttotals(false); + myitem.order = await Order.updateTotals(myitem.order); + await this.updatecarttotals(false); await this.updateExtraOrder(); await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false }); @@ -152,7 +176,6 @@ class Cart { } } - async addItem(itemorder) { // this.items.push(itemorder); @@ -160,7 +183,7 @@ class Cart { this.items[ind] = {}; this.items[ind].order = itemorder; this.items[ind].order = Order.updateTotals(this.items[ind].order); - this.updatecarttotals(false); + await this.updatecarttotals(false); await this.updateExtraOrder(); return ind; @@ -168,8 +191,8 @@ class Cart { async removeItem(orderId) { // this.items.push(itemorder); - this.items = this.items.filter(item => item.order._id.toString() !== orderId.toString()); - this.updatecarttotals(false); + this.items = this.items.filter((item) => item.order._id.toString() !== orderId.toString()); + await this.updatecarttotals(false); await this.updateExtraOrder(); } @@ -184,108 +207,98 @@ class Cart { userId: this.userId, department: this.department, note: this.note, + codice_sconto: this.codice_sconto, note_ordine_gas: this.note_ordine_gas, - modify_at: this.modify_at - }) - return newCart + 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 updateOrderTotals(order, updateCalcPrice) { + order.TotalPriceProductCalc = 0; + if (updateCalcPrice) { + order.TotalPriceProduct = 0; } + const qty = order.quantity + order.quantitypreordered; + this.totalQty += qty; + + let recscontisticheTrovate = await Scontistica.find({ + idapp: order.idapp, + code: this.codice_sconto?.toUpperCase(), + applica: shared_consts.SCONTI_APPLICA.A_TUTTI, + }).lean(); + + const scontiDaUsare = recscontisticheTrovate?.length ? recscontisticheTrovate : order.scontisticas || []; + const priceCalc = this.calcolaPrezzoScontato(order, qty, scontiDaUsare); + + order.TotalPriceProductCalc += priceCalc; + + if (updateCalcPrice) { + order.TotalPriceProduct += priceCalc; + order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2)); + } + + this.totalPriceCalc += priceCalc; + this.totalPrice += order.TotalPriceProduct; + } + + calcolaPrezzoScontato(order, qtyTotale, sconti = []) { + if (!sconti || sconti.length === 0) { + return order.price * qtyTotale; + } + + let scontiApplicati = []; + let qtaRimanente = qtyTotale; + let qtaNonScontata = 0; + + // Applica sconti non cumulativi + while (qtaRimanente > 0) { + let scontoScelto = null; + + for (const sconto of sconti.filter((s) => !s.cumulativo)) { + if (qtaRimanente >= s.qta) { + scontoScelto = { ...sconto, qtadascontare: s.qta }; + break; // prendi il primo valido (puoi migliorare scegliendo il più vantaggioso) + } + } + + if (scontoScelto) { + scontiApplicati.push(scontoScelto); + qtaRimanente -= scontoScelto.qtadascontare; + } else { + qtaNonScontata = qtaRimanente; + qtaRimanente = 0; + } + } + + let prezzoTotale = 0; + + for (const sconto of scontiApplicati) { + if (sconto.perc_sconto > 0) { + prezzoTotale += sconto.qtadascontare * order.price * (1 - sconto.perc_sconto / 100); + } else if (sconto.price > 0) { + prezzoTotale += sconto.price; + } + } + + if (qtaNonScontata > 0) { + prezzoTotale += qtaNonScontata * order.price; + } + + return prezzoTotale; } async updateExtraOrder() { try { - let arrGas = []; - const precnoteordgas = this.note_ordine_gas + const precnoteordgas = this.note_ordine_gas; this.note_ordine_gas = ''; - for (const rec in this.items) { + for (const rec in this.items) { let order = this.items[rec].order; if (!order) { order = this.items[rec]; @@ -296,8 +309,7 @@ class Cart { if (recGas) { if (recGas.note_ordine_gas) { if (!arrGas.includes(recGas._id.toString())) { - if (this.note_ordine_gas) - this.note_ordine_gas += '
' + if (this.note_ordine_gas) this.note_ordine_gas += '
'; this.note_ordine_gas += '' + recGas.name + '' + ':
' + recGas.note_ordine_gas; arrGas.push(recGas._id.toString()); @@ -306,7 +318,6 @@ class Cart { } } } - } catch (e) { console.error('Err:', e); } @@ -315,10 +326,10 @@ class Cart { generateArray() { let arr = []; for (let id in this.items) { - arr.push(this.items[id]) + arr.push(this.items[id]); } return arr; } } -module.exports = Cart +module.exports = Cart; diff --git a/src/server/router/cart_router.js b/src/server/router/cart_router.js index 95f56d5..6327f0c 100755 --- a/src/server/router/cart_router.js +++ b/src/server/router/cart_router.js @@ -10,6 +10,8 @@ var server_constants = require('../tools/server_constants'); var { Project } = require('../models/project'); +const Scontistica = require('../models/scontistica'); + var { authenticate, auth_default } = require('../middleware/authenticate'); const _ = require('lodash'); @@ -28,26 +30,46 @@ const paypal_config = require('../configs/paypal-config') const paypal = require('paypal-rest-sdk') */ -const CartClass = require('../modules/Cart') +const CartClass = require('../modules/Cart'); const Cart = require('../models/cart'); const OrdersCart = require('../models/orderscart'); //GET cart router.get('/:userId', authenticate, async function (req, res, next) { - let userId = req.params.userId - let idapp = req.user.idapp + let userId = req.params.userId; + let idapp = req.user.idapp; return await Cart.getCartByUserId(userId, idapp) .then((cart) => { - if (cart) - return res.send({ code: server_constants.RIS_CODE_OK, cart }); - else - return res.send({ code: server_constants.RIS_CODE_OK, cart: null }); - }).catch((err) => { + if (cart) return res.send({ code: server_constants.RIS_CODE_OK, cart }); + else return res.send({ code: server_constants.RIS_CODE_OK, cart: null }); + }) + .catch((err) => { console.error('Err', err); return res.send({ code: server_constants.RIS_CODE_ERR, cart: null }); }); +}); -}) +async function aggiornaCarrello(mycartpar, userId, idapp) { + try { + let mycart = mycartpar; + + if (!mycart) mycart = await Cart.getCartByUserId(userId, idapp); + + if (!mycart) { + return null; + } + + let newCart = await CartClass.constructByCart(mycart); + // order = await Product.updateProductInOrder(order); + await newCart.updatecarttotals(true); + await newCart.updateExtraOrder(); + + return newCart; + } catch (e) { + console.error('Err AggiornaCarrello', e); + return null; + } +} //POST cart router.post('/:userId', authenticate, async function (req, res, next) { @@ -60,7 +82,6 @@ router.post('/:userId', authenticate, async function (req, res, next) { try { let mycart = await Cart.getCartByUserId(userId, idapp); - if (!order) { return res.send({ code: server_constants.RIS_CODE_OK, cart: null }); } @@ -78,15 +99,14 @@ router.post('/:userId', authenticate, async function (req, res, next) { // no cart save empty cart to database then return response let nuovo = false; if (!mycart) { - let oldCart = new CartClass(order) + let oldCart = new CartClass(order); cart = await Cart.createCart(oldCart.generateModel()); mycart = await Cart.getCartByUserId(userId, idapp); nuovo = true; } - - let newCart = CartClass.constructByCart(mycart); + let newCart = await CartClass.constructByCart(mycart); // order = await Product.updateProductInOrder(order); if (!nuovo) { // Controlla se sto inserendo un prodotto con 2 Negozi, non permetterlo ! @@ -101,35 +121,35 @@ router.post('/:userId', authenticate, async function (req, res, next) { myord = arrord ? arrord[0] : null; } } else { - return res.send({ code: server_constants.RIS_CODE_ERR, cart: null, myord: null, msgerr: 'Non è possibile acquistare nello stesso ordine, su negozi differenti!' }); + return res.send({ + code: server_constants.RIS_CODE_ERR, + cart: null, + myord: null, + msgerr: 'Non è possibile acquistare nello stesso ordine, su negozi differenti!', + }); } } else { - newCart.updatecarttotals(true); + await newCart.updatecarttotals(true); await newCart.updateExtraOrder(); const arrord = await Order.getTotalOrderById(order._id); myord = arrord ? arrord[0] : null; } cart = await Cart.updateCartByCartId(mycart._id, newCart.generateModel()); - if (cart) { const carttot = await Cart.getCartByUserId(userId, idapp); - if (order.idProduct) - product = await Product.getProductById(order.idProduct); - else if (order.product) - product = await Product.getProductById(order.product._id); + if (order.idProduct) product = await Product.getProductById(order.idProduct); + else if (order.product) product = await Product.getProductById(order.product._id); return res.send({ code: server_constants.RIS_CODE_OK, cart: carttot, myord, product }); } else { console.error('Err:', err); return res.send({ code: server_constants.RIS_CODE_ERR, cart: null, myord: null }); } - } catch (e) { console.error('Err:', e); return res.send({ code: server_constants.RIS_CODE_ERR, cart: 0 }); } - -}) +}); router.delete('/:userId', authenticate, async function (req, res) { console.log('DELETE Item'); @@ -140,17 +160,16 @@ router.delete('/:userId', authenticate, async function (req, res) { const mycart = await Cart.getCartByUserId(userId, idapp); const ord = await Order.findOne({ _id: orderId }); - let idProduct = '' + let idProduct = ''; let product = null; - if (ord) - idProduct = ord.idProduct; + if (ord) idProduct = ord.idProduct; // Rimuovere l'Ordine const recremoved = await Order.deleteOne({ _id: orderId }); if (recremoved) { // Rimuovere l'id sul Carrello - let newCart = CartClass.constructByCart(mycart); + let newCart = await CartClass.constructByCart(mycart); await newCart.removeItem(orderId); let carttot = null; const cart = await Cart.updateCartByCartId(mycart._id, newCart.generateModel()); @@ -161,29 +180,27 @@ router.delete('/:userId', authenticate, async function (req, res) { product = await Product.getProductById(idProduct); } - console.log('carttot', carttot) + console.log('carttot', carttot); return res.send({ code: server_constants.RIS_CODE_OK, cart: carttot, product }); } return res.send({ code: server_constants.RIS_CODE_ERR, cart: null }); }); - //PUT cart router.put('/:userId', authenticate, async function (req, res, next) { - let userId = req.params.userId - let requestProduct = req.body - let { productId, color, size } = requestProduct.product + let userId = req.params.userId; + let requestProduct = req.body; + let { productId, color, size } = requestProduct.product; try { - try { const cart = await Cart.getCartByUserId(userId); try { const myprod = await Product.getProductByID(productId); - let newCart = oldCart.add(myprod, productId, { color, size }) + let newCart = oldCart.add(myprod, productId, { color, size }); //exist cart in databse if (cart.length > 0) { @@ -193,7 +210,7 @@ router.put('/:userId', authenticate, async function (req, res, next) { totalQty: newCart.totalQty, totalPrice: newCart.totalPrice, totalPriceCalc: newCart.totalPriceCalc, - userId: userId + userId: userId, }); res.json(result); } catch (err) { @@ -206,16 +223,15 @@ router.put('/:userId', authenticate, async function (req, res, next) { totalQty: newCart.totalQty, totalPrice: newCart.totalPrice, totalPriceCalc: newCart.totalPriceCalc, - userId: userId - } + userId: userId, + }; try { const resultCart = await Cart.createCart(newCartobj); } catch (err) { - return next(err) + return next(err); } res.status(201).json(resultCart); } - } catch (err) { return next(err); } @@ -223,32 +239,132 @@ router.put('/:userId', authenticate, async function (req, res, next) { const product = await Product.getProductById(productId); return res.send({ code: server_constants.RIS_CODE_OK, product }); - } catch (err) { - return next(err) + return next(err); } - let oldCart = new CartClass(c || {}) - + let oldCart = new CartClass(c || {}); } catch (e) { return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 }); } +}); -}) - -//POST cart -router.post('/:userId/createorderscart', authenticate, async function (req, res, next) { +router.post('/:userId/app_sc', authenticate, async function (req, res, next) { let idapp = req.body.idapp; let cart_id = req.body.cart_id; let userId = req.params.userId; - - let status = req.body.status; - let note = req.body.note; + + let codice_sconto = req.body.code; let options = req.body.options; + let mycart = null; + let valido = false; + let errmsg = ''; + try { let mycart = await Cart.findOne({ _id: cart_id }).lean(); + if (codice_sconto === 'RIMUOVI') { + mycart = await Cart.findOneAndUpdate({ _id: cart_id }, { $set: { codice_sconto: '' } }, { new: true }).lean(); + return res.send({ mycart, valido, msg: 'Codice Sconto rimosso', rimuovi: true }); + } + + // attendi 3 secondi prima di poter inviare una nuova richiesta + await tools.attendiNSecondi(1); + + if (codice_sconto) { + const condSconto = { $regex: new RegExp(`^${codice_sconto}$`, 'i') }; + recscontisticheTrovate = await Scontistica.find({ + idapp: idapp, + code: condSconto, + applica: shared_consts.SCONTI_APPLICA.A_TUTTI, + }).lean(); + + if (recscontisticheTrovate && recscontisticheTrovate.length > 0) { + if (mycart.codice_sconto !== codice_sconto) { + mycart.codice_sconto = codice_sconto; + await Cart.updateOne({ _id: cart_id }, { $set: { codice_sconto: codice_sconto } }); + } + valido = true; + + mycart = await aggiornaCarrello(mycart, userId, idapp); + } else { + errmsg = `Codice sconto "${codice_sconto}" non valido oppure scaduto`; + } + } + + return res.send({ mycart, valido, errmsg, recsconto: recscontisticheTrovate }); + } catch (e) { + console.error('Err Applica Sconto', e); + return res.send({ valido: false, mycart: null, errmsg: e.message }); + } +}); + +// Recupera il carrello +async function getCartById(cart_id) { + const cart = await Cart.findOne({ _id: cart_id }).lean(); + return cart; +} + +// Crea o aggiorna un ordine partendo dal cart +async function createOrUpdateOrderFromCart({ idapp, cart, userId, status, note }) { + let numorder = await OrdersCart.getLastNumOrder(idapp); + let numord_pers = await OrdersCart.getLastNumOrdPers(userId, idapp); + + let myorderCart = await OrdersCart.getRecCartByUserId(userId, idapp, numorder); + if (!myorderCart) { + numorder++; + numord_pers++; + myorderCart = new OrdersCart({ + idapp, + items: cart.items, + totalQty: cart.totalQty, + totalPrice: cart.totalPrice, + totalPriceCalc: cart.totalPriceCalc, + note_ordine_gas: cart.note_ordine_gas, + userId, + status, + note, + codice_sconto: cart.codice_sconto, + numorder, + numord_pers, + created_at: new Date(), + modify_at: new Date(), + }); + } + + return myorderCart; +} + +// Gestisce l'invio ordine (checkout) +async function handleCheckout({ myorderCart, mycart, userId, idapp, req, options, userDest }) { + try { + const ris = await OrdersCart.updateOrdersCartById(-1, myorderCart); + await Order.updateStatusOrders(mycart.items, shared_consts.OrderStatus.CHECKOUT_SENT); + + await Cart.deleteCartByCartId(mycart._id); + + const orders = await OrdersCart.getOrdersCartByUserId(userId, idapp, myorderCart.numorder); + if (orders?.[0]) { + await OrdersCart.updateCmd(orders[0], shared_consts.OrderStatus.CHECKOUT_SENT, true, req, options); + await sendemail.sendEmail_OrderProduct(userDest.lang, idapp, orders[0], userDest); + + const updatedOrder = await OrdersCart.findById(myorderCart._id).lean(); + return { status: ris.status, orders, recOrderCart: updatedOrder }; + } + } catch (err) { + console.error('Errore durante il checkout:', err); + throw err; + } +} + +//POST cart +router.post('/:userId/createorderscart', authenticate, async function (req, res) { + const { idapp, cart_id, status, note, options } = req.body; + const userId = req.params.userId; + + try { + const mycart = await getCartById(cart_id); if (!mycart) { return res.send({ code: server_constants.RIS_CODE_OK, @@ -257,93 +373,43 @@ router.post('/:userId/createorderscart', authenticate, async function (req, res, }); } - let numorder = await OrdersCart.getLastNumOrder(idapp); - let numord_pers = await OrdersCart.getLastNumOrdPers(userId, idapp); - - // Esiste l'ordine ? - let myorderCart = await OrdersCart.getRecCartByUserId(userId, idapp, numorder); - if (!myorderCart) { - - // crea il nuovo numero d'ordine - numorder++; - numord_pers++; - - // SE non esiste allora lo creo ! - myorderCart = new OrdersCart({ - idapp, - items: mycart.items, - totalQty: mycart.totalQty, - totalPrice: mycart.totalPrice, - totalPriceCalc: mycart.totalPriceCalc, - note_ordine_gas: mycart.note_ordine_gas, - userId, - status, - note, - numorder, - numord_pers, - created_at: new Date(), - modify_at: new Date(), - }) - } - statusOrderCart = myorderCart.status; - const idordercart = myorderCart._id; + let myorderCart = await createOrUpdateOrderFromCart({ idapp, cart: mycart, userId, status, note }); + let statusOrderCart = myorderCart.status; const userDest = await User.findById(userId).lean(); - if (!!mycart) { - if (status === shared_consts.OrderStatus.CHECKOUT_SENT) { + if (status === shared_consts.OrderStatus.CHECKOUT_SENT) { + try { + const checkoutResult = await handleCheckout({ + myorderCart, + mycart, + userId, + idapp, + req, + options, + userDest, + }); - try { - const ris = await OrdersCart.updateOrdersCartById(-1, myorderCart); - // Gestisci il risultato qui - await Order.updateStatusOrders(mycart.items, status); - - const myris = ris; - // Cancella il Cart appena salvato in OrdersCart - - return Cart.deleteCartByCartId(mycart._id) - .then((ris) => { - - return OrdersCart.getOrdersCartByUserId(userId, idapp, numorder) - .then(async (orders) => { - if (!!orders) { - - if (orders[0]) { - await OrdersCart.updateCmd(orders[0], status, true, req, options); - - // Invia la email dell'Ordine - sendemail.sendEmail_OrderProduct(userDest.lang, idapp, orders[0], userDest) - .then(async (ris) => { - myorderCart = await OrdersCart.findById(idordercart).lean(); - return res.send({ - code: server_constants.RIS_CODE_OK, - status: myris.status, - orders: orders, - recOrderCart: myorderCart - }); - }); - } - } - }); - }) - - } catch (err) { - console.error("Errore durante l'aggiornamento dell'ordine:", err); - return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 }); - } + return res.send({ + code: server_constants.RIS_CODE_OK, + status: checkoutResult.status, + orders: checkoutResult.orders, + recOrderCart: checkoutResult.recOrderCart, + }); + } catch (err) { + return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 }); } - } + return res.send({ code: server_constants.RIS_CODE_OK, status: statusOrderCart, - recOrderCart: myorderCart + recOrderCart: myorderCart, }); } catch (e) { - console.error('Err', e); + console.error('Errore generale:', e); return res.send({ code: server_constants.RIS_CODE_ERR, status: 0, recOrderCart: null }); } - }); //POST cart @@ -356,22 +422,19 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res, const { User } = require('../models/user'); - let myOrdersCart = await OrdersCart.findOne({ idapp, _id: order_id }).lean(); - if ((userId !== String(req.user._id)) && !User.isManager(req.user.perm)) { + if (userId !== String(req.user._id) && !User.isManager(req.user.perm)) { // I'm trying to write something not mine! return res.status(404).send({ code: server_constants.RIS_CODE_TODO_CREATING_NOTMYUSER }); } try { if (!!myOrdersCart) { - let fields_to_update = { status }; - await OrdersCart.findOneAndUpdate({ _id: order_id }, { $set: fields_to_update } - , { new: false }) - .then(async (ris) => { + await OrdersCart.findOneAndUpdate({ _id: order_id }, { $set: fields_to_update }, { new: false }).then( + async (ris) => { const userDest = await User.findById(myOrdersCart.userId).lean(); if (ris) { @@ -390,15 +453,14 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res, } if (ordertype !== '') { - sendemail.sendEmail_Order(userDest.lang, idapp, myOrdersCart, userDest, ordertype, status) - .then((ris) => { - - }) + sendemail + .sendEmail_Order(userDest.lang, idapp, myOrdersCart, userDest, ordertype, status) + .then((ris) => {}); } } } - - }) + } + ); let orderscart = null; @@ -410,14 +472,11 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res, } return res.send({ code: server_constants.RIS_CODE_OK, status, orders: orderscart }); - } } catch (e) { console.error('err', e); return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 }); } - - }); //POST cart @@ -428,24 +487,22 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) { const { User } = require('../models/user'); try { + let queryord = []; - let queryord = [] - - let filtroOrdini = [] + let filtroOrdini = []; if (idGasordine) { const gasordine = { $match: { idGasordine: { - $type: "objectId", // Checks if the field is of type ObjectId - $eq: new ObjectId(idGasordine) // Compares the value to a specific ObjectId - } - } - } - queryord.push(gasordine) + $type: 'objectId', // Checks if the field is of type ObjectId + $eq: new ObjectId(idGasordine), // Compares the value to a specific ObjectId + }, + }, + }; + queryord.push(gasordine); } - const query = [ { $lookup: { @@ -506,15 +563,15 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) { }, { $lookup: { - from: "orderscarts", - localField: "_id", - foreignField: "items.order", - as: "matchingOrders", + from: 'orderscarts', + localField: '_id', + foreignField: 'items.order', + as: 'matchingOrders', }, }, { $match: { - "matchingOrders": { + matchingOrders: { $ne: [], }, }, @@ -539,10 +596,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) { }, totalQuantity: { $sum: { - $add: [ - '$quantity', - '$quantitypreordered', - ], + $add: ['$quantity', '$quantitypreordered'], }, }, totalPrice_acquistato: { @@ -550,10 +604,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) { $multiply: [ '$product.price_acquistato', { - $add: [ - '$quantity', - '$quantitypreordered', - ], + $add: ['$quantity', '$quantitypreordered'], }, ], }, @@ -563,10 +614,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) { $multiply: [ '$product.price', { - $add: [ - '$quantity', - '$quantitypreordered', - ], + $add: ['$quantity', '$quantitypreordered'], }, ], }, @@ -580,25 +628,22 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) { $sort: { name: 1, }, - } - ] + }, + ]; - queryord = [...queryord, ...query] + queryord = [...queryord, ...query]; filtroOrdini = queryord; const arrout = await Order.aggregate(filtroOrdini); for (const rec of arrout) { - } return res.send({ code: server_constants.RIS_CODE_OK, arrout }); - } catch (e) { console.error('Err', e); } - }); module.exports = router; diff --git a/src/server/tools/shared_nodejs.js b/src/server/tools/shared_nodejs.js index 36f9981..c20db01 100755 --- a/src/server/tools/shared_nodejs.js +++ b/src/server/tools/shared_nodejs.js @@ -1224,6 +1224,11 @@ module.exports = { // Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato - PUNTI_PER_POLLICE: 96 + PUNTI_PER_POLLICE: 96, + + SCONTI_APPLICA: { + NESSUNO: 0, + A_TUTTI: 1, + } };