Files
fielderp-server/controllers/partner.controller.js
T

195 lines
5.4 KiB
JavaScript

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);
}
};