308 lines
8.0 KiB
JavaScript
308 lines
8.0 KiB
JavaScript
import {
|
|
createPartner,
|
|
getPartnerById,
|
|
getPartnerByQuery,
|
|
getPartnersByQuery,
|
|
getAllPartners,
|
|
updatePartner,
|
|
aggregatePartner,
|
|
} from "../models/Partner/operations";
|
|
import { aggregateAccess } from "../models/Access/operations";
|
|
import {
|
|
createApproval,
|
|
updateApproval,
|
|
aggregateApproval,
|
|
} from "../models/Approval/operations";
|
|
import dayjs from "dayjs";
|
|
import { ObjectId } from "mongodb";
|
|
|
|
export const createPartnerController = async (req, res) => {
|
|
try {
|
|
const { user } = res.locals;
|
|
|
|
const accessRole = await aggregateAccess([
|
|
{
|
|
$match: {
|
|
user: ObjectId.createFromHexString(user.id),
|
|
},
|
|
},
|
|
{
|
|
$lookup: {
|
|
from: "roles",
|
|
localField: "role",
|
|
foreignField: "_id",
|
|
as: "role",
|
|
},
|
|
},
|
|
{
|
|
$unwind: {
|
|
path: "$role",
|
|
preserveNullAndEmptyArrays: true,
|
|
},
|
|
},
|
|
]);
|
|
|
|
console.log("ACCESS ROLE", accessRole[0]?.role?.modules);
|
|
|
|
const isAutoApproved = accessRole[0]?.role?.modules?.some(
|
|
({ module, permission }) => {
|
|
return module === "partner" && permission === "authorize";
|
|
},
|
|
);
|
|
|
|
const partnerPayload = {
|
|
...req.body,
|
|
createdBy: user.id,
|
|
createdOn: dayjs().toISOString(),
|
|
temp: true,
|
|
isApproved: isAutoApproved,
|
|
};
|
|
|
|
const approvalPayload = {
|
|
entity: partner.id,
|
|
type: "partner",
|
|
createdBy: user.id,
|
|
createdOn: dayjs().toISOString(),
|
|
};
|
|
|
|
if (isAutoApproved) {
|
|
approvalPayload.approvedBy = user.id;
|
|
approvalPayload.approvedOn = dayjs().toISOString();
|
|
approvalPayload.isAutoApproved = true;
|
|
approvalPayload.isApproved = true;
|
|
}
|
|
|
|
const partner = await createPartner(partnerPayload);
|
|
|
|
const approval = await createApproval(approvalPayload);
|
|
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: "orders", // Ensure this matches your actual collection name
|
|
localField: "_id",
|
|
foreignField: "partner",
|
|
as: "partnerOrders",
|
|
},
|
|
},
|
|
|
|
// 3. Calculate Invoice Metrics without unwinding (Satisfies Reqs #3, #4, #5)
|
|
{
|
|
$addFields: {
|
|
totalOrdersCount: { $size: "$partnerOrders" },
|
|
pendingOrPartialOrdersCount: {
|
|
$size: {
|
|
$filter: {
|
|
input: "$partnerOrders",
|
|
as: "order",
|
|
cond: {
|
|
$in: ["$$order.status", ["INPROGRESS", "COMPLETED"]],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
// Note: Your schema uses "PAID", assuming that correlates to "COMPLETED"
|
|
totalOrdersAmount: { $sum: "$partnerOrders.total" },
|
|
},
|
|
},
|
|
|
|
// 4. Remove the heavy invoices array from memory before doing more lookups
|
|
{
|
|
$project: {
|
|
partnerOrders: 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 getPartnersByQuery({ isApproved: true });
|
|
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);
|
|
}
|
|
};
|
|
|
|
export const approvePartnerController = async (req, res, next) => {
|
|
try {
|
|
const { user } = res.locals;
|
|
const { id } = req.params;
|
|
|
|
const approval = await updateApproval(id, {
|
|
isApproved: true,
|
|
isAutoApproved: false,
|
|
approvedBy: user.id,
|
|
approvedOn: dayjs().toISOString(),
|
|
});
|
|
|
|
const partner = await updatePartner(approval.entity, {
|
|
isApproved: true,
|
|
temp: true,
|
|
});
|
|
|
|
res.status(200).json({ result: partner });
|
|
} catch (error) {
|
|
console.log("approvePartnerController Error", error);
|
|
next(error);
|
|
}
|
|
};
|
|
|
|
export const getUnapprovedPartnersController = async (req, res, next) => {
|
|
try {
|
|
const pipeline = [
|
|
{
|
|
$match: {
|
|
isApproved: false,
|
|
},
|
|
},
|
|
{
|
|
$lookup: {
|
|
from: "partners",
|
|
localField: "entity",
|
|
foreignField: "_id",
|
|
as: "partner",
|
|
},
|
|
},
|
|
{
|
|
$unwind: {
|
|
path: "$partner",
|
|
},
|
|
},
|
|
];
|
|
|
|
const unapprovedPartners = await aggregateApproval(pipeline);
|
|
|
|
res.status(200).json({ result: unapprovedPartners });
|
|
} catch (error) {
|
|
console.log("getUnapprovedPartnersController Error", error);
|
|
next(error);
|
|
}
|
|
};
|