import { createPartner, getPartnerById, getPartnerByQuery, getPartnersByQuery, getAllPartners, updatePartner, aggregatePartner, } from "../models/Partner/operations"; import dayjs from "dayjs"; import { ObjectId } from "mongodb"; export const createPartnerController = async (req, res) => { try { const { user } = res.locals; const partner = await createPartner({ ...req.body, createdBy: user.id, createdOn: dayjs().toISOString(), }); res.status(200).json({ result: partner }); } catch (error) { console.log("createPartnerController Error", error); next(error); } }; export const getPartnerController = async (req, res, next) => { try { const { id } = req.params; const pipeline = [ // 1. Match the specific partner (Satisfies Req #1) { $match: { _id: ObjectId.createFromHexString(id), }, }, // 2. Fetch all invoices for this partner { $lookup: { from: "invoices", // Ensure this matches your actual collection name localField: "_id", foreignField: "customer", as: "partnerInvoices", }, }, // 3. Calculate Invoice Metrics without unwinding (Satisfies Reqs #3, #4, #5) { $addFields: { totalInvoicesCount: { $size: "$partnerInvoices" }, pendingOrPartialInvoicesCount: { $size: { $filter: { input: "$partnerInvoices", as: "invoice", cond: { $in: ["$$invoice.status", ["PENDING", "PARTIAL"]], }, }, }, }, // Note: Your schema uses "PAID", assuming that correlates to "COMPLETED" totalInvoicesAmount: { $sum: "$partnerInvoices.total" }, }, }, // 4. Remove the heavy invoices array from memory before doing more lookups { $project: { partnerInvoices: 0, }, }, // 5. Lookup Venues and nested Users/Profiles (Satisfies Reqs #2 & #6) { $lookup: { from: "venues", let: { partnerId: "$_id" }, pipeline: [ // Match venues to the partner (Assuming 'entity' field links to Partner _id) { $match: { $expr: { $eq: ["$entity", "$$partnerId"] }, }, }, // Lookup Assignments for this specific venue { $lookup: { from: "assignments", let: { venueId: "$_id" }, pipeline: [ { $match: { $expr: { $eq: ["$venue", "$$venueId"] }, isActive: true, // Optional: ensuring we only get active assignments }, }, // Lookup the User for the assignment { $lookup: { from: "users", localField: "user", foreignField: "_id", as: "userDetails", }, }, { $unwind: { path: "$userDetails", preserveNullAndEmptyArrays: true, }, }, // Lookup the Profile for the assigned User { $lookup: { from: "profiles", localField: "user", foreignField: "user", as: "userProfile", }, }, { $unwind: { path: "$userProfile", preserveNullAndEmptyArrays: true, }, }, // Clean up the assignment shape { $project: { _id: 1, targetedVisits: 1, user: "$userDetails", profile: "$userProfile", }, }, ], as: "assignedUsers", }, }, ], as: "venues", }, }, ]; const partner = await aggregatePartner(pipeline); if (!partner?.length) { throw new Error("Partner not found"); } res.status(200).json({ result: partner[0] || {} }); } catch (error) { console.log("getPartnerController Error", error); next(error); } }; export const getAllPartnersController = async (req, res) => { try { const partners = await getAllPartners(); res.status(200).json({ result: partners }); } catch (error) { console.log("getAllPartnersController Error", error); next(error); } }; export const updatePartnerController = async (req, res) => { try { const { id } = req.params; const partner = await updatePartner(id, req.body); res.status(200).json({ result: partner }); } catch (error) { console.log("updatePartnerController Error", error); next(error); } }; export const deletePartnerController = async (req, res, next) => { try { const { id } = req.params; const partner = await updatePartner(id, { isActive: false }); res.status(200).json({ result: partner }); } catch (error) { console.log("deletePartnerController Error", error); next(error); } };