feat: calc profit endpoint
All checks were successful
Spell Check / Spell Check with Typos (push) Successful in 8s
All checks were successful
Spell Check / Spell Check with Typos (push) Successful in 8s
This commit is contained in:
parent
b4df1a5d4e
commit
9bd24b5a83
1 changed files with 45 additions and 13 deletions
|
|
@ -322,6 +322,13 @@ export class StatsController extends Controller {
|
||||||
) {
|
) {
|
||||||
const record = await prisma.quotationProductServiceList.findMany({
|
const record = await prisma.quotationProductServiceList.findMany({
|
||||||
include: {
|
include: {
|
||||||
|
work: {
|
||||||
|
include: {
|
||||||
|
productOnWork: {
|
||||||
|
select: { stepCount: true, productId: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
product: {
|
product: {
|
||||||
select: {
|
select: {
|
||||||
agentPrice: true,
|
agentPrice: true,
|
||||||
|
|
@ -335,9 +342,16 @@ export class StatsController extends Controller {
|
||||||
vatIncluded: true,
|
vatIncluded: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requestWork: {
|
||||||
|
include: {
|
||||||
|
stepStatus: true,
|
||||||
|
creditNote: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
quotation: {
|
quotation: {
|
||||||
select: {
|
select: {
|
||||||
agentPrice: true,
|
agentPrice: true,
|
||||||
|
creditNote: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -358,26 +372,44 @@ export class StatsController extends Controller {
|
||||||
take: limit,
|
take: limit,
|
||||||
});
|
});
|
||||||
|
|
||||||
let income = 0;
|
const data = record.map((v) => {
|
||||||
let expenses = 0;
|
|
||||||
let netProfit = 0;
|
|
||||||
|
|
||||||
record.forEach((v) => {
|
|
||||||
const originalPrice = v.product.serviceCharge;
|
const originalPrice = v.product.serviceCharge;
|
||||||
const productExpenses = precisionRound(
|
const productExpenses = precisionRound(
|
||||||
originalPrice + (v.product.serviceChargeVatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
originalPrice + (v.product.serviceChargeVatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||||
);
|
);
|
||||||
const finalPrice = v.pricePerUnit * v.amount * (1 + config.vat);
|
const finalPrice = v.pricePerUnit * v.amount * (1 + config.vat);
|
||||||
|
|
||||||
income += finalPrice;
|
return v.requestWork.map((w) => {
|
||||||
expenses += productExpenses;
|
const creditNote = w.creditNote;
|
||||||
netProfit += finalPrice - productExpenses;
|
const roundCount = v.work?.productOnWork.find((p) => p.productId)?.stepCount || 1;
|
||||||
|
const successCount = w.stepStatus.filter(
|
||||||
|
(s) => s.workStatus !== RequestWorkStatus.Canceled,
|
||||||
|
).length;
|
||||||
|
|
||||||
|
const income = creditNote
|
||||||
|
? precisionRound(productExpenses * successCount)
|
||||||
|
: precisionRound(finalPrice);
|
||||||
|
const expenses = creditNote
|
||||||
|
? precisionRound(productExpenses * successCount)
|
||||||
|
: precisionRound(productExpenses * roundCount);
|
||||||
|
const netProfit = creditNote ? 0 : precisionRound(finalPrice - expenses);
|
||||||
|
|
||||||
|
return {
|
||||||
|
income,
|
||||||
|
expenses,
|
||||||
|
netProfit,
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return data.flat().reduce(
|
||||||
income: precisionRound(income),
|
(a, c) => {
|
||||||
expenses: precisionRound(expenses),
|
a.income += c.income;
|
||||||
netProfit: precisionRound(netProfit),
|
a.expenses += c.expenses;
|
||||||
};
|
a.netProfit += c.netProfit;
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
{ income: 0, expenses: 0, netProfit: 0 },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue