diff --git a/app/controllers/establishment.controller.js b/app/controllers/establishment.controller.js index 0ddfaee..16ddcbe 100644 --- a/app/controllers/establishment.controller.js +++ b/app/controllers/establishment.controller.js @@ -180,37 +180,77 @@ exports.createEstablishment = async (req, res) => { await sendEmailService(establishment_user.email, 'establishment_user_creation_to_user', placeHolderData); // insert establishment_products - if (Array.isArray(establishment_products) && establishment_products.length > 0) { + // if (Array.isArray(establishment_products) && establishment_products.length > 0) { - // remove duplicates from request itself - let uniqueProducts = [...new Set(establishment_products.map(x => x.product_id))]; - // now check which already exist for this establishment + // // remove duplicates from request itself + // let uniqueProducts = [...new Set(establishment_products.map(x => x.product_id))]; + // // now check which already exist for this establishment + // const existing = await EstablishmentProduct.findAll({ + // where: { + // establishment_id: establishment.id, + // product_id: uniqueProducts + // }, + // attributes: ['product_id'] + // }); + + // const existingIds = existing.map(x => x.product_id); + + // // filter only new ones (not existing) + // const newProducts = uniqueProducts + // .filter(pid => !existingIds.includes(pid)) + // .map(pid => ({ + // establishment_id: establishment.id, + // product_id: pid, + // created_at: new Date(), + // })); + + // // only insert if have new ones + // if (newProducts.length) { + // await EstablishmentProduct.bulkCreate(newProducts); + // } + // } + + // insert establishment_products + if (Array.isArray(establishment_products) && establishment_products.length > 0) + { + + // remove duplicates inside request + const uniqueProducts = establishment_products.reduce((acc, item) => { + if (!acc.some(p => p.product_id === item.product_id)) { + acc.push(item); + } + return acc; + }, []); + + // find already existing products const existing = await EstablishmentProduct.findAll({ where: { establishment_id: establishment.id, - product_id: uniqueProducts + product_id: uniqueProducts.map(x => x.product_id) }, - attributes: ['product_id'] + attributes: ["product_id"] }); const existingIds = existing.map(x => x.product_id); - // filter only new ones (not existing) - const newProducts = uniqueProducts - .filter(pid => !existingIds.includes(pid)) - .map(pid => ({ + // filter only NEW ones and include audit fields + const insertData = uniqueProducts + .filter(x => !existingIds.includes(x.product_id)) + .map(x => ({ establishment_id: establishment.id, - product_id: pid, - created_at: new Date(), + product_id: x.product_id, + created_by: x.created_by || null, + action_done_by: x.action_done_by || "admin_user", + created_at: new Date() })); - // only insert if have new ones - if (newProducts.length) { - await EstablishmentProduct.bulkCreate(newProducts); + if (insertData.length > 0) { + await EstablishmentProduct.bulkCreate(insertData); } } - // 🔹 Return success response + + //Return success response return res.status(201).send({ status: "success", message: "Establishment and linked user created successfully", @@ -497,7 +537,26 @@ exports.getEstablishmentById = async (req, res) => { { model: EstablishmentProduct, as: "establishment_products", - attributes: ["id", "establishment_id", "product_id"], + where: { is_active: 1 }, + attributes: [ + "id", + "establishment_id", + "product_id", + "action_done_by", + + [ + Sequelize.literal(` + CASE + WHEN establishment_products.action_done_by = 'admin_users' THEN + (SELECT name FROM admin_users WHERE admin_users.id = establishment_products.created_by) + WHEN establishment_products.action_done_by = 'establishment_users' THEN + (SELECT name FROM establishment_users WHERE establishment_users.id = establishment_products.created_by) + ELSE NULL + END + `), + "created_user" + ] + ], include: [ { model: Product, @@ -505,7 +564,9 @@ exports.getEstablishmentById = async (req, res) => { attributes: ["product_name", "hs_code", "hs_description"], }, ], - }, + } + + ], }); @@ -562,26 +623,101 @@ exports.updateEstablishment = async (req, res) => { } // update establishment products - if (Array.isArray(establishment_products)) { - let incomingIds = establishment_products.map(e => e.product_id); + // if (Array.isArray(establishment_products)) { + // let incomingIds = establishment_products.map(e => e.product_id); + + // const oldProducts = await EstablishmentProduct.findAll({ where:{ establishment_id:id } }); + // const oldIds = oldProducts.map(e => e.product_id); + + // // remove products not in new list + // const removeIds = oldIds.filter(v => !incomingIds.includes(v)); + // if (removeIds.length) { + // await EstablishmentProduct.destroy({ where:{ establishment_id:id, product_id:removeIds } }); + // } + + // // add only new ones + // const newIds = incomingIds.filter(v => !oldIds.includes(v)); + + // for (let pid of newIds) { + // await EstablishmentProduct.create({ establishment_id:id, product_id:pid, created_by: req.user.id}); + // } + // } + + if (Array.isArray(establishment_products)) { + + const incoming = establishment_products; + const incomingIds = incoming.map(e => e.product_id); + + const oldProducts = await EstablishmentProduct.findAll({ + where: { establishment_id: id } + }); - const oldProducts = await EstablishmentProduct.findAll({ where:{ establishment_id:id } }); const oldIds = oldProducts.map(e => e.product_id); - // remove products not in new list + // SOFT-REMOVE products not present anymore const removeIds = oldIds.filter(v => !incomingIds.includes(v)); - if (removeIds.length) { - await EstablishmentProduct.destroy({ where:{ establishment_id:id, product_id:removeIds } }); + + if (removeIds.length > 0) { + + // find matching incoming data for audit fields + const removedData = incoming.find( + p => removeIds.includes(p.product_id) + ); + + await EstablishmentProduct.update( + { + is_active: 0, + updated_by: removedData?.updated_by , + action_done_by: removedData?.action_done_by || null, + updated_at: new Date() + }, + { + where: { + establishment_id: id, + product_id: removeIds + } + } + ); } - // add only new ones - const newIds = incomingIds.filter(v => !oldIds.includes(v)); - for (let pid of newIds) { - await EstablishmentProduct.create({ establishment_id:id, product_id:pid, created_by: req.user.id}); + // ADD new active products + const newItems = incoming.filter(p => !oldIds.includes(p.product_id)); + + for (const item of newItems) { + await EstablishmentProduct.create({ + establishment_id: id, + product_id: item.product_id, + is_active: 1, + created_by: item.created_by || null, + action_done_by: item.action_done_by, + created_at: new Date() + }); + } + + // UPDATE existing product metadata + const updateItems = incoming.filter(p => oldIds.includes(p.product_id)); + + for (const item of updateItems) { + await EstablishmentProduct.update( + { + is_active: 1, + updated_by: item.updated_by || null, + action_done_by: item.action_done_by, + updated_at: new Date() + }, + { + where: { + establishment_id: id, + product_id: item.product_id + } + } + ); } } + + return res.json({ status:"success", message:"Updated successfully" , data:"" }); } catch(err) { diff --git a/app/models/establishmentProduct.model.js b/app/models/establishmentProduct.model.js index c7d24d4..5eb7ed0 100644 --- a/app/models/establishmentProduct.model.js +++ b/app/models/establishmentProduct.model.js @@ -25,6 +25,10 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.INTEGER, allowNull: false, }, + action_done_by: { + type: DataTypes.STRING, + allowNull: false, + }, updated_at: { type: DataTypes.DATE, allowNull: true, diff --git a/app/routes/routes.js b/app/routes/routes.js index 371a857..1b55eca 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -474,6 +474,9 @@ router.get("/testEmail", establishmentController.testEmail); * - product_id * properties: * product_id: { type: integer } + * created_by: { type: integer } + * updated_by: { type: integer } + * action_done_by: { type: string } * responses: * 201: * description: Establishment and linked user created successfully @@ -633,6 +636,9 @@ router.get("/establishments/:id",[verifySignature, verifyToken], establishmentCo * - product_id * properties: * product_id: { type: integer } + * created_by: { type: integer } + * updated_by: { type: integer } + * action_done_by: { type: string } * responses: * 200: * description: Establishment updated successfully