Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
18 views7 pages

Other Method For Graph

The document outlines a function that retrieves Purchase Request (PR), Purchase Order (PO), Invoice, and Goods Receipt Note (GRN) data based on various parameters. It processes and aggregates this data into a structured response, including calculations for total and approved amounts for each category. Additionally, it prepares chart options for visualizing the financial data in a user interface.

Uploaded by

DQS INDIA
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views7 pages

Other Method For Graph

The document outlines a function that retrieves Purchase Request (PR), Purchase Order (PO), Invoice, and Goods Receipt Note (GRN) data based on various parameters. It processes and aggregates this data into a structured response, including calculations for total and approved amounts for each category. Additionally, it prepares chart options for visualizing the financial data in a user interface.

Uploaded by

DQS INDIA
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

exports.

getPrDataPoDataInvoiceDataGrnDataByGraph = async (req, res) => {


try {
const {
pr_id,
company_id,
prCategory,
type,
priority,
emp_id,
poInvoice_id
} = req.body;

const resultArray = [];

// -------- Fetch PR Data (Service PR or Item PR) -------- //


if (pr_id && prCategory) {
const prIncludeOptions = [
{ model: db.tbl_prWorkFlowApprove },
{ model: db.employee },
{ model: db.tbl_prFileUpload }
];

if (prCategory === 'Service PR') {


prIncludeOptions.push({ model: db.tbl_prServiceMapping });
} else if (prCategory === 'Item PR') {
prIncludeOptions.push(
{
model: db.tbl_prItemMapping,
where: { isDeleted: false },
required: false
},
{
model: db.tbl_prBOMMapping,
required: false
}
);
}

const prData = await db.tbl_pr.findAll({


where: { pr_id, company_id },
include: prIncludeOptions
});

if (prData.length) {
await Promise.all(prData.map(async (pr) => {
const department = await db.tbl_department.findOne({
where: { department_id: pr.department_id }
});
pr.dataValues.department_name = department?.department_name ||
null;
}));

resultArray.push({
prData: prData
});
}
}

// -------- Fetch PO + Invoice Data -------- //


if (type === "PO_INVOICE") {
const poList = await db.tbl_po.findAll();

for (const po of poList) {


const invoices = await db.tbl_poInvoice.findAll({
where: {
po_id: po.po_id,
...(poInvoice_id && { poInvoice_id }),
isDeleted: false
}
});
const [data] = await db.sequelize.query(`
SELECT * FROM tbl_poInvoices poi
WHERE poi.po_id = :po_id
`, {
replacements: { po_id: po.po_id }
});
const poItems = await db.tbl_PoItemMapping.findAll({
where: { po_id: po.po_id }
});

const totalAmount = poItems.reduce((sum, item) => sum +


(item.priceIncludingCharges || 0), 0);

const itemsArray = [];


for (const invoice of invoices) {
const items = await db.tbl_poInvoiceMapping.findAll({
where: {
poInvoice_id: invoice.poInvoice_id,
status: "ACTIVE"
}
});
itemsArray.push(...items);
}

resultArray.push({
poData: po,
poitemData: poItems,
itemsArray,
invoiceData: invoices,
totalAmount,
data
});
}
}

// -------- Fetch GRN Data -------- //


if (type === "GRN") {
const [poResults] = await db.sequelize.query(`
SELECT po.*, rf.rfpCategory
FROM tbl_pos po
LEFT JOIN tbl_rfps rf ON po.rfp_id = rf.rfp_id
WHERE
(rf.rfpCategory IN ('ItemRFP', 'BomRFP') OR rf.rfpCategory IS
NULL)
AND (po.createdBy = :emp_id OR po.grnCreator = :emp_id)
AND po.poStatus = 'ACCEPTED'
ORDER BY po.po_id DESC;
`, {
replacements: { emp_id }
});

const enrichedPoList = await Promise.all(poResults.map(async (po) => {


const poItems = await db.tbl_PoItemMapping.findAll({
where: { po_id: po.po_id }
});

const enrichedItems = await Promise.all(poItems.map(async (item) =>


{
const vendor = await db.tbl_vendor.findOne({
where: { vendor_id: item.vendor_id },
attributes: ['supplierName']
});

const itemDetails = await db.tbl_item.findOne({


where: { item_id: item.item_id },
attributes: ['itemDescription', 'brand', 'model']
});

return {
...item.dataValues,
supplierName: vendor?.supplierName || null,
description: itemDetails?.itemDescription || null,
brand: itemDetails?.brand || null,
model: itemDetails?.model || null
};
}));

return {
...po,
poItemMappings: enrichedItems
};
}));

resultArray.push({
grnData: enrichedPoList
});
}

// -------- Final Response -------- //


return res.status(200).send({
code: 200,
message: "Data fetched successfully",
result: resultArray
});

} catch (error) {
console.error("Error in getPrDataPoDataInvoiceDataGrnDataByGraph:", error);
return res.status(500).json({
code: 500,
message: error.message || "Internal server error"
});
}
};

getAllPrDataPoDataInvoiceDataGrnDataByGraph() {
const body: any = {
company_id: this.companyId,
type: "PO_INVOICE",
emp_id: this.employeeLoginId,
poInvoice_id: 456,
prCategory: "Item PR",
pr_id: 370
};

this.dashboard_service.getAllPrDataPoDataInvoiceDataGrnDataByGraph(body).subscribe(
(res: any) => {
if (res && res.code === 200 && res.result && res.result.length > 0) {
// Extract data correctly from the response structure
const result = res.result;

// PR data is in the first element of result array under prData key


const prData = result[0]?.prData || [];

// PO and invoice data are in subsequent elements of the result array


const poInvoiceData = result.slice(1) || [];

// --- PR Amount calculations ---


const totalPrAmount = prData.reduce((sum: number, pr: any) =>
sum + (parseFloat(pr.totalAmount) || 0), 0);

const approvedPrAmount = prData


.filter((pr: any) => pr.prCategoryStatus === "Approved")
.reduce((sum: number, pr: any) => sum + (parseFloat(pr.totalAmount) ||
0), 0);

// --- PO Amount calculations ---


const totalPoAmount = poInvoiceData.reduce((sum: number, po: any) => {
const amount = po.totalAmount || 0;
return sum + parseFloat(amount);
}, 0);

const approvedPoAmount = poInvoiceData


.filter((po: any) => po.poData && po.poData.poStatus === "ACCEPTED")
.reduce((sum: number, po: any) => {
const amount = po.totalAmount || 0;
return sum + parseFloat(amount);
}, 0);

// --- Invoice Amount calculations ---


const totalInvoiceAmount = poInvoiceData.reduce((sum: number, po: any) =>
{
if (!po.data || !Array.isArray(po.data)) return sum;

return sum + po.data.reduce((innerSum: number, invoice: any) => {


// Use totalAmount from PO for each active invoice since
invoiceAmount isn't in the response
return innerSum + (invoice.isDeleted === 0 ? po.totalAmount : 0);
}, 0);
}, 0);

const approvedInvoiceAmount = poInvoiceData.reduce((sum: number, po: any)


=> {
if (!po.data || !Array.isArray(po.data)) return sum;
return sum + po.data.reduce((innerSum: number, invoice: any) => {
return innerSum + (invoice.isDeleted === 0 && invoice.paymentStatus
=== "PAID" ?
po.totalAmount : 0);
}, 0);
}, 0);

// --- GRN Amount calculations ---


const totalGrnAmount = poInvoiceData
.filter((po: any) => po.poData && po.poData.grnStatus !== null)
.reduce((sum: number, po: any) => {
// Since grnAmount isn't in the response, use totalAmount as a
fallback
return sum + parseFloat(po.totalAmount || 0);
}, 0);

const approvedGrnAmount = poInvoiceData


.filter((po: any) => po.poData && po.poData.grnStatus === "Created")
.reduce((sum: number, po: any) => {
return sum + parseFloat(po.totalAmount || 0);
}, 0);

// Log calculated values for debugging


console.log("Calculated Values:", {
totalPrAmount,
approvedPrAmount,
totalPoAmount,
approvedPoAmount,
totalInvoiceAmount,
approvedInvoiceAmount,
totalGrnAmount,
approvedGrnAmount
});

// Create chart options with proper values


this.chartOptions1 = {
animationEnabled: true,
theme: "light2",
exportEnabled: true,
title: {
text: "Current Year Spent Analysis",
fontSize: 20
},
axisX: {
labelFontSize: 12,
labelAngle: 0
},
axisY: {
title: "Amount in Rupees (₹)",
titleFontSize: 14,
interlacedColor: "#EBF2FA",
tickColor: "azure",
titleFontColor: "#4f81bc",
prefix: "₹",
includeZero: true
},
toolTip: {
shared: true,
contentFormatter: function(e: any) {
let content = "<strong>" + e.entries[0].dataPoint.label +
"</strong><br/>";
for (let i = 0; i < e.entries.length; i++) {
content += "<span style='color: " + e.entries[i].dataSeries.color
+ ";'>" +
e.entries[i].dataSeries.name + "</span>: <strong>₹" +
e.entries[i].dataPoint.y.toLocaleString() + "</strong><br/>";
}
return content;
}
},
legend: {
cursor: "pointer",
fontSize: 14,
itemclick: function(e: any) {
if (typeof e.dataSeries.visible === "undefined" ||
e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
e.chart.render();
}
},
dataPointWidth: 50,
data: [
{
type: "column",
name: "Created",
legendText: "Created",
showInLegend: true,
color: "#4472c4",
dataPoints: [
{ label: "Purchase Request", y: totalPrAmount || 0 },
{ label: "Purchase Order", y: totalPoAmount || 0 },
{ label: "Invoice", y: totalInvoiceAmount || 0 },
{ label: "GRN", y: totalGrnAmount || 0 }
]
},
{
type: "column",
name: "Approved",
legendText: "Approved",
showInLegend: true,
color: "#5cb85c",
dataPoints: [
{ label: "Purchase Request", y: approvedPrAmount || 0 },
{ label: "Purchase Order", y: approvedPoAmount || 0 },
{ label: "Invoice", y: approvedInvoiceAmount || 0 },
{ label: "GRN", y: approvedGrnAmount || 0 }
]
}
]
};

// Make sure the chart renders after data is available


setTimeout(() => {
if (this.cdr) {
this.cdr.detectChanges();
console.log("Chart options updated and change detection triggered");
}
}, 100);
}
else {
console.error("Error fetching data:", res);
}
},
(error) => {
console.error("API call failed:", error);
}
);
}

You might also like