const shared_consts = require('../tools/shared_nodejs'); const express = require('express'); const router = express.Router(); const sendemail = require('../sendemail'); const tools = require('../tools/general'); 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'); const Product = require('../models/product'); const Order = require('../models/order'); const Variant = require('../models/variant'); const { User } = require('../models/user'); const { ObjectId } = require('mongodb'); /*const Department = require('../models/Department') const Category = require('../models/Category') const TypedError = require('../modules/ErrorHandler') const paypal_config = require('../configs/paypal-config') const paypal = require('paypal-rest-sdk') */ 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; 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) => { 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; mycart = await Cart.getCartCompletoByCartId(mycart._id, idapp); let newCart = await CartClass.constructByCart(mycart); if (newCart) return newCart.aggiornaCarrello(); return newCart; } catch (e) { console.error('Err AggiornaCarrello', e); return null; } } //POST cart router.post('/:userId', authenticate, async function (req, res, next) { let idapp = req.body.idapp; let userId = req.params.userId; let addqty = req.body.addqty; let subqty = req.body.subqty; let order = req.body.order; try { let mycart = await Cart.getCartByUserId(userId, idapp); if (!order) { return res.send({ code: server_constants.RIS_CODE_OK, cart: null }); } // const myorder = Order.getOrderByID(order._id); if (!addqty && !subqty && order) { order._id = await Order.createOrder(order, mycart.codice_sconto); if (!order._id) { return res.send({ code: server_constants.RIS_CODE_ERR, cart: 0 }); } } let cart = null; let product = null; // no cart save empty cart to database then return response let nuovo = false; if (!mycart) { let oldCart = new CartClass(order); cart = await Cart.createCart(oldCart.generateModel()); mycart = await Cart.getCartByUserId(userId, idapp); nuovo = true; } let newCart = await CartClass.constructByCart(mycart); // order = await Product.updateProductInOrder(order); if (!nuovo) { // Controlla se sto inserendo un prodotto con 2 Negozi, non permetterlo ! if (newCart.isSameStorehouse(order)) { if (addqty) { myord = await newCart.addqty(order); } else if (subqty) { myord = await newCart.subqty(order); } else { const ind = await newCart.addItem(order); const arrord = await Order.getTotalOrderById(order._id); 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!', }); } } else { 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); 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'); let idapp = req.query.idapp; let userId = req.params.userId; let orderId = req.query.orderId; const mycart = await Cart.getCartByUserId(userId, idapp); const ord = await Order.findOne({ _id: orderId }); let idProduct = ''; let product = null; if (ord) idProduct = ord.idProduct; // Rimuovere l'Ordine const recremoved = await Order.deleteOne({ _id: orderId }); if (recremoved) { // Rimuovere l'id sul Carrello let newCart = await CartClass.constructByCart(mycart); await newCart.removeItem(orderId); let carttot = null; const cart = await Cart.updateCartByCartId(mycart._id, newCart.generateModel()); carttot = await Cart.getCartByUserId(userId, idapp); if (idProduct) { product = await Product.getProductById(idProduct); } 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; try { try { const cart = await Cart.getCartByUserId(userId); try { const myprod = await Product.getProductByID(productId); let newCart = oldCart.add(myprod, productId, { color, size }); //exist cart in databse if (cart.length > 0) { try { const result = await Cart.updateCartByUserId(userId, { items: newCart.items, totalQty: newCart.totalQty, totalPrice: newCart.totalPrice, totalPriceCalc: newCart.totalPriceCalc, totalPriceIntero: newCart.totalPriceIntero, userId: userId, }); res.json(result); } catch (err) { return next(err); } } else { //no cart in database let newCartobj = { items: newCart.items, totalQty: newCart.totalQty, totalPrice: newCart.totalPrice, totalPriceCalc: newCart.totalPriceCalc, totalPriceIntero: newCart.totalPriceIntero, userId: userId, }; try { const resultCart = await Cart.createCart(newCartobj); } catch (err) { return next(err); } res.status(201).json(resultCart); } } catch (err) { return next(err); } const product = await Product.getProductById(productId); return res.send({ code: server_constants.RIS_CODE_OK, product }); } catch (err) { return next(err); } let oldCart = new CartClass(c || {}); } catch (e) { return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 }); } }); 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 codice_sconto = req.body.code; let options = req.body.options; let mycart = null; let valido = false; let errmsg = ''; let recscontisticaTrovata = null; try { let mycart = await Cart.getCartCompletoByCartId(cart_id, idapp); // 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(); mycart = await aggiornaCarrello(mycart, userId, idapp); 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 recscontisticheTrovate = await CartClass.getRecSconto(idapp, codice_sconto, true); if (recscontisticheTrovate && recscontisticheTrovate.length > 0) { recscontisticaTrovata = recscontisticheTrovate[0]; } if (recscontisticaTrovata) { if (mycart.codice_sconto !== codice_sconto) { mycart.codice_sconto = codice_sconto; mycart.descr_sconto = recscontisticaTrovata.description; await Cart.updateOne({ _id: cart_id }, { $set: { codice_sconto, descr_sconto: mycart.descr_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: recscontisticaTrovata }); } 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, totalPriceIntero: cart.totalPriceIntero, note_ordine_gas: cart.note_ordine_gas, userId, status, note, codice_sconto: cart.codice_sconto, descr_sconto: cart.descr_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) { try { const { idapp, cart_id, status, note, options } = req.body; const userId = req.params.userId; // console.log('createorderscart', cart_id); const mycart = await getCartById(cart_id); if (!mycart) { return res.send({ code: server_constants.RIS_CODE_OK, status: 0, recOrderCart: null, }); } let myorderCart = await createOrUpdateOrderFromCart({ idapp, cart: mycart, userId, status, note }); let statusOrderCart = myorderCart.status; const userDest = await User.findById(userId).lean(); if (status === shared_consts.OrderStatus.CHECKOUT_SENT) { try { const checkoutResult = await handleCheckout({ myorderCart, mycart, userId, idapp, req, options, userDest, }); 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 }); } } // console.log('SEND OK', statusOrderCart); return res.send({ code: server_constants.RIS_CODE_OK, status: statusOrderCart, recOrderCart: myorderCart, }); } catch (e) { console.error('Errore generale:', e); return res.send({ code: server_constants.RIS_CODE_ERR, status: 0, recOrderCart: null }); } }); //POST cart router.post('/:userId/ordercartstatus', authenticate, async function (req, res, next) { let idapp = req.body.idapp; let userId = req.params.userId; let order_id = req.body.order_id; let status = req.body.status; let options = req.body.options; 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)) { // 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) => { const userDest = await User.findById(myOrdersCart.userId).lean(); if (ris) { let ordertype = ''; // Aggiorna gli Stati Interni ! myOrdersCart = await OrdersCart.updateCmd(myOrdersCart, status, true, options); if ((options.hasOwnProperty('sendmail') && options.sendmail) || !options.hasOwnProperty('sendmail')) { if (status === shared_consts.OrderStatus.ORDER_CONFIRMED) { ordertype = 'order_confirmed'; } else if (status === shared_consts.OrderStatus.DELIVERED) { ordertype = 'order_consegnato'; } else if (status === shared_consts.OrderStatus.CANCELED) { ordertype = 'order_canceled'; } if (ordertype !== '') { sendemail .sendEmail_Order(userDest.lang, idapp, myOrdersCart, userDest, ordertype, status) .then((ris) => {}); } } } } ); let orderscart = null; if (User.isManager(req.user.perm)) { // Prende Tutti gli Ordini ! orderscart = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false); } else { orderscart = await OrdersCart.getOrdersCartByUserId(req.user.id, idapp, 0, false); } 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 router.post('/:userId/gestord', authenticate, async function (req, res, next) { let idapp = req.body.idapp; let idGasordine = req.body.idGasordine; const { User } = require('../models/user'); try { let queryord = []; 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); } const query = [ { $lookup: { from: 'products', localField: 'idProduct', foreignField: '_id', as: 'product', }, }, { $unwind: { path: '$product', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'gasordines', localField: 'idGasordine', foreignField: '_id', as: 'gasordine', }, }, { $unwind: { path: '$gasordine', preserveNullAndEmptyArrays: true, }, }, { $match: { $or: [ { quantity: { $gt: 0, }, }, { quantitypreordered: { $gt: 0, }, }, ], }, }, { $lookup: { from: 'orderscarts', localField: '_id', foreignField: 'items.order', as: 'matchingOrders', }, }, { $match: { matchingOrders: { $ne: [], }, }, }, { $group: { _id: '$product._id', name: { $first: '$product.productInfo.name', }, weight: { $first: '$product.productInfo.weight', }, unit: { $first: '$product.productInfo.unit', }, price_acquistato: { $first: '$product.price_acquistato', }, price: { $first: '$product.price', }, totalQuantity: { $sum: { $add: ['$quantity', '$quantitypreordered'], }, }, totalPrice_acquistato: { $sum: { $multiply: [ '$product.price_acquistato', { $add: ['$quantity', '$quantitypreordered'], }, ], }, }, totalPrice: { $sum: { $multiply: [ '$product.price', { $add: ['$quantity', '$quantitypreordered'], }, ], }, }, count: { $sum: 1, }, }, }, { $sort: { name: 1, }, }, ]; 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;