diff --git a/docs/prova.txt b/docs/prova.txt index 54a043f..e69de29 100644 --- a/docs/prova.txt +++ b/docs/prova.txt @@ -1 +0,0 @@ -"{ \"code\":\"8017977028342\", \"name\":\"Mochi di Riso Integrale Bio - 250g (0828293)\", \"price\":\"10.48\", \"stockQty\":\"4\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__mochi-di-riso-integrale-bio-250g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"6.3\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977001215\", \"name\":\"Malto di Riso Bio - 400g (0706072)\", \"price\":\"5.00\", \"stockQty\":\"4\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__malto-di-riso-bio-400-g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"3.1\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977001338\", \"name\":\"KUZU BIO \", \"price\":\"7.56\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__kuzu-bio.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"5.13\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977004544\", \"name\":\"Sale Marino Integrale FINO\", \"price\":\"1.79\", \"stockQty\":\"6\", \"link\":\"\", \"perc_iva\":\"22\", \"price_acquistato\":\"1\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977034374\", \"name\":\"Bevanda di riso - Rice Drink - 1l (0827622)\", \"price\":\"2.30\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__bevanda-di-riso-rice-drink.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"1.31\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977000669\", \"name\":\"Thain Bio Crema di Sesamo\", \"price\":\"7.00\", \"stockQty\":\"6\", \"link\":\"\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.57\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977001666\", \"name\":\"Malto di Orzo Bio - 400g (0706106)\", \"price\":\"5.18\", \"stockQty\":\"4\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__malto-di-orzo-bio-400g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"3.23\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977002427\", \"name\":\"Acidulato di Umeboshi - 250ml (0706067)\", \"price\":\"4.34\", \"stockQty\":\"4\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__acidulato-di-umeboshi-250-ml.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"3.08\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977043604\", \"name\":\"Tè Bancha Bio\", \"price\":\"2.33\", \"stockQty\":\"12\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__te-bancha-non-tostato.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"1.2\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977013720\", \"name\":\"Pangermoglio con Semi di Lino e Girasole 400 gr. (0828261)\", \"price\":\"6.25\", \"stockQty\":\"3\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__pangermoglio-con-semi-di-lino-e-girasole-400-gr.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.27\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977000515\", \"name\":\"Gomasio Bio alle Alghe - 150g (0706085)\", \"price\":\"4.46\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__gomasio-bio-alle-alghe-150g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"3.15\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8052204790371\", \"name\":\"Uber Granola Proteica Rosè\", \"price\":\"7.09\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__ubergranola-granola-proteica-rose.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.03\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977000614\", \"name\":\"Umeboshi Bio - 100g (0706118)\", \"price\":\"9.43\", \"stockQty\":\"4\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__umeboshi-bio-prugne-salate-la-finestra-sul-cielo.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"6.17\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"4015533015007\", \"name\":\"Succo Verdure \", \"price\":\"4.70\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/verdure.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"3.06\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977034350\", \"name\":\"Bio Avena Drink Senza Glutine - 1l (0845294)\", \"price\":\"2.60\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__avena-drink-senza-glutine-1.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"1.35\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977011696\", \"name\":\"Sciroppo d\\'acero Bio\", \"price\":\"9.40\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__sciroppo-d-acero-canadese-bio-grado-c.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"6.02\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977043550\", \"name\":\"Fette di Semi Bio\", \"price\":\"4.98\", \"stockQty\":\"18\", \"link\":\"\", \"perc_iva\":\"10\", \"price_acquistato\":\"3.21\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977042430\", \"name\":\"Soba Bio - 200g (0001198)\", \"price\":\"6.14\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__soba-bio-giapponese.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.15\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"5600872803133\", \"name\":\"Super colazione Lamponi e Burro di Arachidi\", \"price\":\"6.75\", \"stockQty\":\"6\", \"link\":\"\", \"perc_iva\":\"10\", \"price_acquistato\":\"5.15\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"4015533014994\", \"name\":\"Succo di Barbabietole\", \"price\":\"4.94\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__succo-di-barbabietola-rossa.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"3.06\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"7618500940110\", \"name\":\"Succo di carota\", \"price\":\"4.20\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__succo-di-carote-500ml.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"2.39\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8004192103107\", \"name\":\"Acqua Minerale Naturale \", \"price\":\"0.83\", \"stockQty\":\"6\", \"link\":\"\", \"perc_iva\":\"22\", \"price_acquistato\":\"0.48\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977031496\", \"name\":\"Crunchy con Avena e Cacao - 375g (0706078)\", \"price\":\"5.23\", \"stockQty\":\"3\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__crunchy-con-avena-e-cacao-375g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.04\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977031441\", \"name\":\"Crunchy con Avena e Frutti Rossi - 375g (0706080)\", \"price\":\"5.78\", \"stockQty\":\"3\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__crunchy-con-avena-e-frutti-rossi-375-gr.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.04\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977035944\", \"name\":\"Gomasio alla Curcuma Bio - 150g (0706088)\", \"price\":\"3.77\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__gomasio-alla-curcuma-bio.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"2.43\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977003974\", \"name\":\"Alghe Marine Nori\", \"price\":\"6.90\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__alghe-marine-nori-in-fogli-25-g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"4.09\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977020018\", \"name\":\"Stuoia in Bambù (per Sushi) (0708808)\", \"price\":\"3.30\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__stuoia-in-bambu-per-sushi.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"2.32\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977004278\", \"name\":\"Fagioli Azuki Bio \", \"price\":\"3.98\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__azuki-hokkaido-500g.php\", \"perc_iva\":\"04\", \"price_acquistato\":\"3.17\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977028342\", \"name\":\"Mochi di Riso Integrale Bio - 250g (0828293)\", \"price\":\"10.48\", \"stockQty\":\"4\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__mochi-di-riso-integrale-bio-250g.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"6.3\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977041808\", \"name\":\"Avena Mandorla Drink Bio - 1l (0828642)\", \"price\":\"2.60\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__avena-mandorla-drink-bio-bevanda-a-base-di-avena-e-mandorla.php\", \"perc_iva\":\"22\", \"price_acquistato\":\"1.45\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977043505\", \"name\":\"Crunchy Snack ai Semi - 110gr (0007125)\", \"price\":\"4.15\", \"stockQty\":\"14\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__crunchy-snack-ai-semi.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"3.31\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8016323046863\", \"name\":\"Peasy snack\", \"price\":\"1.55\", \"stockQty\":\"15\", \"link\":\"\", \"perc_iva\":\"10\", \"price_acquistato\":\"1.13\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977043536\", \"name\":\"Mini Crock Bio Avena e Mix di Semi\", \"price\":\"3.25\", \"stockQty\":\"14\", \"link\":\"\", \"perc_iva\":\"10\", \"price_acquistato\":\"2.12\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8056734461442\", \"name\":\"Paccheri Rigati Le Campane\", \"price\":\"3.70\", \"stockQty\":\"12\", \"link\":\"\", \"perc_iva\":\"04\", \"price_acquistato\":\"2.47\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8056734463255\", \"name\":\"Le Pugliesi Foglie di Ulivo con Spinaci Bio\", \"price\":\"3.30\", \"stockQty\":\"12\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__foglie-d-ulivo-con-spinaci-bio.php\", \"perc_iva\":\"04\", \"price_acquistato\":\"2.26\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"4012824406094\", \"name\":\"Infuso Uomo energia Yogi\", \"price\":\"4.18\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__infuso-uomo-energia.php\", \"perc_iva\":\"10\", \"price_acquistato\":\"2.27\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"4012824406100\", \"name\":\"Infuso Donna Energia Yogi\", \"price\":\"4.18\", \"stockQty\":\"6\", \"link\":\"https://www.macrolibrarsi.it/prodotti/__infuso-donna-energia.php#descrizione\", \"perc_iva\":\"10\", \"price_acquistato\":\"2.27\", \"producer_name\":\"La Finestra sul Cielo\"}, { \"code\":\"8017977043307\", \"name\":\"Mochi all\\'Artemisia - 250g (0042682)\", \"price\":\"10.40\", \"stockQty\":\"4\", \"link\":\"\", \"perc_iva\":\"10\", \"price_acquistato\":\"6.3\", \"producer_name\":\"La Finestra sul Cielo\"}, " \ No newline at end of file diff --git a/emails/ecommerce/makeorder/it/html.pug b/emails/ecommerce/makeorder/it/html.pug index a9f632e..b6b1649 100755 --- a/emails/ecommerce/makeorder/it/html.pug +++ b/emails/ecommerce/makeorder/it/html.pug @@ -45,6 +45,7 @@ html - var price = product.order.price - var after_price = product.order.after_price - var qty = product.order.quantity + - var qtypreordered = product.order.quantitypreordered - index = index + 1 table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center") @@ -66,9 +67,14 @@ html tr td(class="sectionContent", valign="top") p Prezzo: #{price} € #{after_price} - tr - td(class="sectionContent", valign="top") - p Quantità: #{qty} + if (qty > 0) + tr + td(class="sectionContent", valign="top") + p Quantità: #{qty} + if (qtypreordereded > 0) + tr + td(class="sectionContent", valign="top") + p Quantità Prenotata: #{qtypreorder} p Note Aggiuntive: #{note} diff --git a/emails/ecommerce/order_confirmed/it/html.pug b/emails/ecommerce/order_confirmed/it/html.pug index 0381c0e..2a1f0ae 100755 --- a/emails/ecommerce/order_confirmed/it/html.pug +++ b/emails/ecommerce/order_confirmed/it/html.pug @@ -45,6 +45,7 @@ html - var price = product.order.product.price - var after_price = product.order.product.after_price - var qty = product.order.product.quantity + - var qtypreordered = product.order.quantitypreordered - index = index + 1 table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center") @@ -66,9 +67,14 @@ html tr td(class="sectionContent", valign="top") p Prezzo: #{price} € #{after_price} - tr - td(class="sectionContent", valign="top") - p Quantità: #{qty} + if (qty > 0) + tr + td(class="sectionContent", valign="top") + p Quantità: #{qty} + if (qtypreordered > 0) + tr + td(class="sectionContent", valign="top") + p Quantità Prenotata: #{qtypreordered} p Note Aggiuntive: #{note} diff --git a/src/server/models/gasordine.js b/src/server/models/gasordine.js new file mode 100755 index 0000000..3bdd0d8 --- /dev/null +++ b/src/server/models/gasordine.js @@ -0,0 +1,72 @@ + mongoose = require('mongoose').set('debug', false) +const Schema = mongoose.Schema; + +const tools = require('../tools/general'); + +mongoose.Promise = global.Promise; +mongoose.level = "F"; + + +// Resolving error Unknown modifier: $pushAll +mongoose.plugin(schema => { + schema.options.usePushEach = true +}); + +const gasordineSchema = new Schema({ + active: { + type: Boolean, + }, + idapp: { + type: String, + }, + name: { + type: String, + }, + description: { + type: String, + }, + referente: { + type: String, + }, + city: { + type: String, + }, + img: { + type: String, + }, + dataora_chiusura: { + type: Date, + }, + dataora_ritiro: { + type: Date, + }, +}); + +var Gasordine = module.exports = mongoose.model('Gasordine', gasordineSchema); + +module.exports.getFieldsForSearch = function () { + return [ + {field: 'name', type: tools.FieldType.string}, + {field: 'description', type: tools.FieldType.string}, + ] +}; + +module.exports.executeQueryTable = function (idapp, params) { + params.fieldsearch = this.getFieldsForSearch(); + return tools.executeQueryTable(this, idapp, params); +}; + +module.exports.findAllIdApp = async function (idapp) { + const myfind = { idapp }; + + return await Gasordine.find(myfind); +}; + + +module.exports.getGasordineByID = function (id, callback) { + Gasordine.findById(id, callback); +} + +module.exports.createIndexes((err) => { + if (err) throw err; +}); diff --git a/src/server/models/order.js b/src/server/models/order.js index 84de28b..7738984 100755 --- a/src/server/models/order.js +++ b/src/server/models/order.js @@ -2,6 +2,7 @@ const mongoose = require('mongoose').set('debug', false) const Schema = mongoose.Schema; +const shared_consts = require('../tools/shared_nodejs'); const { ObjectID } = require('mongodb'); @@ -27,6 +28,7 @@ const orderSchema = new Schema({ idStorehouse: { type: Schema.Types.ObjectId, ref: 'StoreHouse' }, idScontisticas: [{ type: Schema.Types.ObjectId, ref: 'Scontistica' }], idProvider: { type: Schema.Types.ObjectId, ref: 'Provider' }, + idGasordine: { type: Schema.Types.ObjectId, ref: 'Gasordine' }, price: { type: Number, default: 0, @@ -44,11 +46,15 @@ const orderSchema = new Schema({ type: Number, default: 0, }, + quantitypreordered: { + type: Number, + default: 0, + }, TotalPriceProduct: { type: Number, default: 0, }, - evaso: { // e quindi è stato tolto dal magazzino (aggiornando il campo StockQty) + evaso: { // e quindi è stato tolto dal magazzino (aggiornando il campo stockQty) type: Boolean, default: false, }, @@ -164,6 +170,14 @@ module.exports.findAllIdApp = async function (idapp) { as: 'provider' } }, + { + $lookup: { + from: 'gasordines', + localField: 'idGasordine', + foreignField: '_id', + as: 'gasordine' + } + }, { $lookup: { from: 'scontisticas', @@ -189,6 +203,12 @@ module.exports.findAllIdApp = async function (idapp) { path: '$provider', preserveNullAndEmptyArrays: true, }, + }, + { + $unwind: { + path: '$gasordine', + preserveNullAndEmptyArrays: true, + }, } ]; @@ -255,7 +275,7 @@ module.exports.updateTotals = function (order) { let sconti_da_applicare = []; if (order.scontisticas) { - let qtadascontare = order.quantity + let qtadascontare = order.quantity + order.quantitypreordered let qtanonscontata = 0 while (qtadascontare > 0) { @@ -295,7 +315,7 @@ module.exports.updateTotals = function (order) { } } else { - mypricecalc = order.price * order.quantity; + mypricecalc = (order.price * order.quantity) + (order.price * order.quantitypreordered); } order.TotalPriceProduct += mypricecalc; @@ -341,6 +361,14 @@ module.exports.getTotalOrderById = async function (id) { as: 'provider' } }, + { + $lookup: { + from: 'gasordines', + localField: 'idGasordine', + foreignField: '_id', + as: 'gasordine' + } + }, { $lookup: { from: 'scontisticas', @@ -372,7 +400,108 @@ module.exports.getTotalOrderById = async function (id) { path: '$provider', preserveNullAndEmptyArrays: true, }, - } + }, + { + $unwind: { + path: '$gasordine', + preserveNullAndEmptyArrays: true, + }, + }, + { + $lookup: { + from: 'orders', + let: { productId: '$product._id' }, + pipeline: [ + { + $match: { + $expr: { + $and: [ + { $eq: ['$idProduct', '$$productId'] }, + { $lt: ['$status', shared_consts.OrderStatus.ORDER_CONFIRMED] } + ] + } + } + }, + { + $group: { + _id: null, + totalQty: { $sum: '$quantity' }, + } + } + ], + as: 'productOrders' + } + }, + { + $lookup: { + from: 'orders', + let: { productId: '$product._id' }, + pipeline: [ + { + $match: { + $expr: { + $and: [ + { $eq: ['$idProduct', '$$productId'] }, + { $lt: ['$status', shared_consts.OrderStatus.ORDER_CONFIRMED] } + ] + } + } + }, + { + $group: { + _id: null, + totalQtyPreordered: { $sum: '$quantitypreordered' } + } + } + ], + as: 'productPreOrders' + } + }, + { + $addFields: { + 'product.QuantitaOrdinateInAttesa': { + $ifNull: [ + { + $cond: { + if: { $isArray: '$productOrders' }, + then: { $arrayElemAt: ['$productOrders.totalQty', 0] }, + else: 0 + } + }, + 0 + ] + }, + 'product.QuantitaPrenotateInAttesa': { + $ifNull: [ + { + $cond: { + if: { $isArray: '$productPreOrders' }, + then: { $arrayElemAt: ['$productPreOrders.totalQtyPreordered', 0] }, + else: 0 + } + }, + 0 + ] + }, + }, + }, + { + $addFields: { + 'product.quantityAvailable': { + $subtract: ["$product.stockQty", "$product.QuantitaOrdinateInAttesa"], + }, + 'product.bookableAvailableQty': { + $subtract: ["$product.bookableQty", "$product.QuantitaPrenotateInAttesa"], + } + } + }, + { + $unset: 'productOrders' + }, + { + $unset: 'productPreOrders' + }, + ]; return await Order.aggregate(query); diff --git a/src/server/models/orderscart.js b/src/server/models/orderscart.js index c39c721..f4258e7 100755 --- a/src/server/models/orderscart.js +++ b/src/server/models/orderscart.js @@ -8,6 +8,7 @@ var { User } = require('../models/user'); const Storehouse = require('../models/storehouse'); const Provider = require('../models/provider'); +const Gasordine = require('../models/gasordine'); const Product = require('../models/product'); const tools = require('../tools/general'); @@ -22,7 +23,7 @@ const OrdersCartSchema = new Schema({ numord_pers: { type: Number }, userId: { type: Schema.Types.ObjectId, ref: 'User' }, totalQty: { type: Number, default: 0 }, - TotalPriceProduct: { type: Number, default: 0 }, + totalQtyPreordered: { type: Number, default: 0 }, totalPrice: { type: Number, default: 0 }, department: { type: String, ref: 'Department' @@ -129,10 +130,10 @@ module.exports.getLastNumOrder = async function (idapp) { module.exports.getLastNumOrdPers = async function (uid, idapp) { let query = { userId: uid, idapp, deleted: false } let numorder = 1; - let numorderrec = await OrdersCart.find(query).sort({ numorder: -1 }).limit(1); + let numorderrec = await OrdersCart.find(query).sort({ numord_pers: -1 }).limit(1); if (numorderrec && numorderrec.length > 0) - numorder = numorderrec[0].numorder; + numorder = numorderrec[0].numord_pers; else numorder = 0; @@ -177,7 +178,7 @@ module.exports.getOrdersCartById = async function (id) { } -module.exports.getOrdersCartByQuery = async function (query) { +module.exports.getOLDOrdersCartByQuery = async function (query) { let myorderscart = await OrdersCart.find(query) .populate('items.order') @@ -202,6 +203,13 @@ module.exports.getOrdersCartByQuery = async function (query) { model: 'Provider' }, }) + .populate({ + path: 'items.order', + populate: { + path: 'idGasordine', + model: 'Gasordine' + }, + }) .populate({ path: 'items.order', populate: { @@ -237,6 +245,8 @@ module.exports.getOrdersCartByQuery = async function (query) { item.order.idStorehouse = item.order.storehouse ? item.order.storehouse._id : ''; item.order.provider = item.order.idProvider; item.order.idProvider = item.order.provider ? item.order.provider._id : ''; + item.order.gasordine = item.order.idGasordine; + item.order.idGasordine = item.order.gasordine ? item.order.gasordine._id : ''; item.order.scontisticas = item.order.scontisticas; item.order.idScontisticas = item.order.idScontisticas ? item.order.idScontisticas._id : ''; } catch (e) { @@ -251,10 +261,95 @@ module.exports.getOrdersCartByQuery = async function (query) { return myorderscart; } -module.exports.getOrdersCartByUserId = async function (uid, idapp, numorder) { + + +module.exports.getOrdersCartByQuery = async function (query) { + + let myorderscart = await OrdersCart.find(query) + .populate('items.order') + .populate({ + path: 'items.order', + populate: { + path: 'idProduct', + model: 'Product' + }, + }) + .populate({ + path: 'items.order', + populate: { + path: 'idProducer', + model: 'Producer' + }, + }) + .populate({ + path: 'items.order', + populate: { + path: 'idProvider', + model: 'Provider' + }, + }) + .populate({ + path: 'items.order', + populate: { + path: 'idGasordine', + model: 'Gasordine' + }, + }) + .populate({ + path: 'items.order', + populate: { + path: 'idStorehouse', + model: 'Storehouse' + }, + }) + .populate({ + path: 'items.order', + populate: { + path: 'idScontisticas', + model: 'Scontistica' + }, + }) + .populate({ + path: 'userId', + model: 'User', + select: '_id name surname username profile', // Specify the fields you want to retrieve + }) + .lean(); + + myorderscart = myorderscart.map(order => { + order.user = order.userId + order.userId = order.user._id + order.items = order.items.map(item => { + if (item.order) { + try { + item.order.product = item.order.idProduct; + item.order.idProduct = item.order.product ? item.order.product._id : ''; + item.order.producer = item.order.idProducer; + item.order.idProducer = item.order.producer ? item.order.producer._id : ''; + item.order.storehouse = item.order.idStorehouse; + item.order.idStorehouse = item.order.storehouse ? item.order.storehouse._id : ''; + item.order.provider = item.order.idProvider; + item.order.idProvider = item.order.provider ? item.order.provider._id : ''; + item.order.gasordine = item.order.idGasordine; + item.order.idGasordine = item.order.gasordine ? item.order.gasordine._id : ''; + item.order.scontisticas = item.order.scontisticas; + item.order.idScontisticas = item.order.idScontisticas ? item.order.idScontisticas._id : ''; + } catch (e) { + console.error('Err: ', e); + } + } + return item; + }); + return order; + }); + + return myorderscart; +} + +module.exports.getOrdersCartByUserId = async function (uid, idapp, numorder, filterStatus) { try { - let query = { idapp, status: { $gte: shared_consts.OrderStatus.CHECKOUT_SENT }, deleted: false } + let query = { idapp, deleted: false } let myorderscart = null; if (numorder > 0) { query.numorder = numorder; @@ -264,6 +359,10 @@ module.exports.getOrdersCartByUserId = async function (uid, idapp, numorder) { query.userId = uid; } + if (filterStatus) { + query.status = { $gte: shared_consts.OrderStatus.CHECKOUT_SENT }; + } + myorderscart = await OrdersCart.getOrdersCartByQuery(query); @@ -299,8 +398,8 @@ module.exports.updateOrdersCartById = function (id, newOrdersCart, callback) { $set: { items: newOrdersCart.items, totalQty: newOrdersCart.totalQty, + totalQtyPreordered: newOrdersCart.totalQtyPreordered, totalPrice: newOrdersCart.totalPrice, - totalPriceProduct: newOrdersCart.totalPriceProduct, userId: userId, status: newOrdersCart.status, numorder: newOrdersCart.numorder, @@ -432,15 +531,18 @@ module.exports.updateStockQtaDalMagazzino = async function (idorderscart) { let order = myorderscart.items[idkey].order; if (!order.evaso) { - const update = { + let update = { $inc: { stockQty: -order.quantity } }; - const ris = await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false }); - if (ris) { - - } + await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false }); + update = { + $inc: { + bookableQty: -order.quantitypreordered + } + }; + await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false }); } } @@ -546,12 +648,17 @@ module.exports.getmsgorderTelegram = async function (ordersCart) { msg += '

Lista Prodotti:'; for (const ord of ordersCart.items) { msg += '
'; - msg += '✅ [' + ord.order.quantity + '] ' + ord.order.product.name + ' (' + ord.order.price + ' € ' + (ord.order.after_price ? ord.order.after_price : '') + ' Tot=' + ord.order.TotalPriceProduct + '€ )'; + let qtystr = '' + if (ord.order.quantity > 0) + qtystr += 'Ordinate: ' + ord.order.quantity + if (ord.order.quantitypreordered > 0) + qtystr += ' Pre-Ordinate: ' + ord.order.quantitypreordered + msg += '✅ [' + qtystr + '] ' + ord.order.product.name + ' (' + ord.order.price + ' € ' + (ord.order.after_price ? ord.order.after_price : '') + ' Tot=' + ord.order.TotalPriceProduct + '€ )'; } msg += '
'; - msg += '
Totale Prodotti: ' + ordersCart.totalQty; + msg += '
Totale Prodotti: ' + ordersCart.totalQty + ordersCart.totalQtyPreordered; msg += '
Totale Ordine: ' + ordersCart.totalPrice + ' € 💰'; diff --git a/src/server/models/product.js b/src/server/models/product.js index c8c5954..6e8336d 100755 --- a/src/server/models/product.js +++ b/src/server/models/product.js @@ -6,6 +6,7 @@ const tools = require('../tools/general'); const Producer = require('../models/producer'); const Storehouse = require('../models/storehouse'); const Provider = require('../models/provider'); +const Gasordine = require('../models/gasordine'); const Scontistica = require('../models/scontistica'); const shared_consts = require('../tools/shared_nodejs'); @@ -96,6 +97,10 @@ const productSchema = new Schema({ type: Number, default: 0, }, + bookableQty: { // Quantità prenotabili + type: Number, + default: 0, + }, quantityLow: { //Soglia disponibilità bassa type: Number, default: 0, @@ -275,27 +280,82 @@ module.exports.findAllIdApp = async function (idapp, code, id) { { $group: { _id: null, - totalQty: { $sum: '$quantity' } + totalQty: { $sum: '$quantity' }, } } ], as: 'productOrders' } }, + { + $lookup: { + from: 'orders', + let: { productId: '$_id' }, + pipeline: [ + { + $match: { + $expr: { + $and: [ + { $eq: ['$idProduct', '$$productId'] }, + { $lt: ['$status', shared_consts.OrderStatus.ORDER_CONFIRMED] } + ] + } + } + }, + { + $group: { + _id: null, + totalQtyPreordered: { $sum: '$quantitypreordered' } + } + } + ], + as: 'productPreOrders' + } + }, { $addFields: { QuantitaOrdinateInAttesa: { - $cond: { - if: { $isArray: '$productOrders' }, - then: { $arrayElemAt: ['$productOrders.totalQty', 0] }, - else: 0 - } + $ifNull: [ + { + $cond: { + if: { $isArray: '$productOrders' }, + then: { $arrayElemAt: ['$productOrders.totalQty', 0] }, + else: 0 + } + }, + 0 + ] + }, + QuantitaPrenotateInAttesa: { + $ifNull: [ + { + $cond: { + if: { $isArray: '$productPreOrders' }, + then: { $arrayElemAt: ['$productPreOrders.totalQtyPreordered', 0] }, + else: 0 + } + }, + 0 + ] + }, + }, + }, + { + $addFields: { + quantityAvailable: { + $subtract: ["$stockQty", "$QuantitaOrdinateInAttesa"], + }, + bookableAvailableQty: { + $subtract: ["$bookableQty", "$QuantitaPrenotateInAttesa"], } } }, { $unset: 'productOrders' }, + { + $unset: 'productPreOrders' + }, ); @@ -352,6 +412,14 @@ module.exports.getProductByID = function (id, callback) { Product.findById(id, callback); } +module.exports.updateProductInOrder = async function (order) { + + if (order.product) + order.product = await Product.getProductById(order.product._id); + + return order; +} + module.exports.createIndexes((err) => { if (err) throw err; }); diff --git a/src/server/modules/Cart.js b/src/server/modules/Cart.js index 1323460..4e940df 100755 --- a/src/server/modules/Cart.js +++ b/src/server/modules/Cart.js @@ -6,18 +6,25 @@ const { ObjectID } = require('mongodb'); const Order = require('../models/order'); class Cart { - constructor(order) { - this.items = {}; - if (!!order) { - this.idapp = order.idapp || 0; - this.items[order._id] = order; - this.userId = order.userId || ""; - } + 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.updatetotals(); } + 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); @@ -34,26 +41,49 @@ class Cart { } } + 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; + } + async addqty(itemorder) { const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id) if (!!myitem) { - myitem.order.quantity++; - myitem.order = Order.updateTotals(myitem.order); + if (this.isAvailableByOrder(myitem.order)) { + myitem.order.quantity++; + } else { + myitem.order.quantitypreordered++; + } + this.updatetotals(); await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false }); - return myitem.order.quantity; + return myitem.order; } } async subqty(itemorder) { try { const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id) - if (!!myitem && myitem.order.quantity > 0) { - myitem.order.quantity--; - myitem.order = Order.updateTotals(myitem.order); + if (!!myitem) { + if (myitem.order.quantitypreordered > 0) { + myitem.order.quantitypreordered--; + } else { + if (myitem.order.quantity > 0) { + myitem.order.quantity--; + } + } this.updatetotals(); await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false }); - return myitem.order.quantity; + return myitem.order; } } catch (e) { console.error('Err: ', e); @@ -79,30 +109,86 @@ class Cart { } generateModel() { - let newCart = new cartModel({ - idapp: this.idapp, - items: this.generateArray(), - totalQty: this.totalQty, - totalPrice: this.totalPrice, - userId: this.userId, - department: this.department, - note: this.note, - modify_at: this.modify_at - }) - - return newCart + try { + let newCart = new cartModel({ + idapp: this.idapp, + items: this.generateArray(), + totalQty: this.totalQty, + totalPrice: this.totalPrice, + userId: this.userId, + department: this.department, + note: this.note, + modify_at: this.modify_at + }) + return newCart + } catch (e) { + console.error('Err', e); + } + return null; } updatetotals() { try { this.totalQty = 0; this.totalPrice = 0; - if (this.items && this.items.length > 0) { - for (const rec of this.items) { - let ord = Order.updateTotals(rec.order); - this.totalQty += ord.quantity; - this.totalPrice += ord.TotalPriceProduct; + for (const rec in this.items) { + let mypricecalc = 0; + + let order = this.items[rec].order; + if (!order) { + order = this.items[rec]; } + 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); + } + order.TotalPriceProduct += mypricecalc; + this.totalPrice += order.TotalPriceProduct; } this.totalPrice = parseFloat(this.totalPrice.toFixed(2)) } catch (e) { diff --git a/src/server/router/cart_router.js b/src/server/router/cart_router.js index ac18228..70c5606 100755 --- a/src/server/router/cart_router.js +++ b/src/server/router/cart_router.js @@ -72,7 +72,6 @@ router.post('/:userId', authenticate, async function (req, res, next) { let cart = null; let product = null; // no cart save empty cart to database then return response - let myqty = 0; let nuovo = false; if (!mycart) { let oldCart = new CartClass(order) @@ -83,16 +82,21 @@ router.post('/:userId', authenticate, async function (req, res, next) { } let newCart = CartClass.constructByCart(mycart); + // order = await Product.updateProductInOrder(order); if (!nuovo) { if (addqty) { - myqty = await newCart.addqty(order); + myord = await newCart.addqty(order); } else if (subqty) { - myqty = await newCart.subqty(order); + myord = await newCart.subqty(order); } else { const ind = newCart.addItem(order); + const arrord = await Order.getTotalOrderById(order._id); + myord = arrord ? arrord[0] : null; } } else { await newCart.updatetotals(); + const arrord = await Order.getTotalOrderById(order._id); + myord = arrord ? arrord[0] : null; } cart = await Cart.updateCartByCartId(mycart._id, newCart.generateModel()); @@ -103,9 +107,10 @@ router.post('/:userId', authenticate, async function (req, res, next) { 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, qty: myqty, product }); + return res.send({ code: server_constants.RIS_CODE_OK, cart: carttot, myord, product }); } else { - return res.send({ code: server_constants.RIS_CODE_ERR, cart: null }); + console.error('Err:', err); + return res.send({ code: server_constants.RIS_CODE_ERR, cart: null, myord: null }); } /* @@ -308,6 +313,15 @@ router.post('/:userId/createorderscart', authenticate, async function (req, res, }) } }) + } else if (status < shared_consts.OrderStatus.CHECKOUT_SENT) { + // Aggiorna il carrello ! + + /*const cartpao = await Cart.getCartByUserId(userId, idapp); + let newCart = CartClass.constructByCart(cartpao); + if (newCart) + await newCart.updatetotals(); + newCart;*/ + } } @@ -377,9 +391,9 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res, if (User.isManager(user.perm)) { // Prende Tutti gli Ordini ! - orderscart = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0); + orderscart = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false); } else { - orderscart = await OrdersCart.getOrdersCartByUserId(req.user.id, idapp, 0); + orderscart = await OrdersCart.getOrdersCartByUserId(req.user.id, idapp, 0, false); } return res.send({ code: server_constants.RIS_CODE_OK, status, orders: orderscart }); diff --git a/src/server/router/index_router.js b/src/server/router/index_router.js index f501fc6..7e6bf39 100755 --- a/src/server/router/index_router.js +++ b/src/server/router/index_router.js @@ -66,6 +66,7 @@ const Cart = require('../models/cart'); const OrdersCart = require('../models/orderscart'); const Storehouse = require('../models/storehouse'); const Provider = require('../models/provider'); +const Gasordine = require('../models/gasordine'); const Scontistica = require('../models/scontistica'); const Department = require('../models/department'); const { Category } = require('../models/category'); @@ -1434,6 +1435,7 @@ function load(req, res, version) { let workers = User.getusersWorkersList(idapp); let storehouses = Storehouse.findAllIdApp(idapp); let providers = Provider.findAllIdApp(idapp); + let gasordines = Gasordine.findAllIdApp(idapp); let scontisticas = Scontistica.findAllIdApp(idapp); let departments = Department.findAllIdApp(idapp); let categories = Category.findAllIdApp(idapp); @@ -1466,9 +1468,9 @@ function load(req, res, version) { cart = Cart.getCartByUserId(req.user.id, idapp); if (User.isManager(req.user.perm)) { // Prende Tutti gli Ordini ! - orderscart = OrdersCart.getOrdersCartByUserId('ALL', idapp, 0); + orderscart = OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false); } else { - orderscart = OrdersCart.getOrdersCartByUserId(req.user.id, idapp, 0); + orderscart = OrdersCart.getOrdersCartByUserId(req.user.id, idapp, 0, false); } } let askedfriends = []; @@ -1523,6 +1525,7 @@ function load(req, res, version) { categories, // 39 providers, scontisticas, + gasordines, ]).then((arrdata) => { // console.table(arrdata); let myuser = req.user; @@ -1607,6 +1610,7 @@ function load(req, res, version) { categories: arrdata[39], providers: arrdata[40], scontisticas: arrdata[41], + gasordines: arrdata[42], }); const prova = 1; diff --git a/src/server/router/orders_router.js b/src/server/router/orders_router.js index 90c3007..de04a13 100755 --- a/src/server/router/orders_router.js +++ b/src/server/router/orders_router.js @@ -30,14 +30,15 @@ const OrdersCart = require('../models/orderscart'); router.get('/:userId', authenticate, function (req, res, next) { let userId = req.body.userId let idapp = req.body.idapp - OrdersCart.getOrdersCartByUserId(userId, idapp, 0, function (err, cart) { - if (err) return next(err) + OrdersCart.getOrdersCartByUserId(userId, idapp, 0, false) + .then((cart) => { + + if (cart) + res.send({ code: server_constants.RIS_CODE_OK, cart }); + else + res.status(400).send(e); + }) - if (cart) - res.send({ code: server_constants.RIS_CODE_OK, cart }); - else - res.status(400).send(e); - }) }) module.exports = router; diff --git a/src/server/router/products_router.js b/src/server/router/products_router.js index fcfd9f2..ac837ff 100755 --- a/src/server/router/products_router.js +++ b/src/server/router/products_router.js @@ -36,9 +36,9 @@ router.post('/', auth_default, async function (req, res, next) { let orders = null; if (await User.isManagerById(userId)) { // Prende Tutti gli Ordini ! - orders = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0); + orders = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false); } else { - orders = await OrdersCart.getOrdersCartByUserId(userId, idapp, 0); + orders = await OrdersCart.getOrdersCartByUserId(userId, idapp, 0, false); } if (products) diff --git a/src/server/tools/globalTables.js b/src/server/tools/globalTables.js index 98674f1..cfa764e 100755 --- a/src/server/tools/globalTables.js +++ b/src/server/tools/globalTables.js @@ -61,6 +61,7 @@ const Cart = require('../models/cart'); const OrdersCart = require('../models/orderscart'); const Storehouse = require('../models/storehouse'); const Provider = require('../models/provider'); +const Gasordine = require('../models/gasordine'); const Scontistica = require('../models/scontistica'); const Department = require('../models/department'); const { Category } = require('../models/category'); @@ -108,6 +109,8 @@ module.exports = { mytable = Storehouse; else if (tablename === 'providers') mytable = Provider; + else if (tablename === 'gasordines') + mytable = Gasordine; else if (tablename === 'scontisticas') mytable = Scontistica; else if (tablename === 'departments')