refactor: update quotation

This commit is contained in:
Methapon Metanipat 2024-10-04 16:48:23 +07:00
parent 353d372dd8
commit 8ae8ec7002
2 changed files with 73 additions and 58 deletions

View file

@ -1,8 +1,3 @@
{
"branch": {
"maxHeadOfficeBranch": 10
},
"personnel": {
"type": ["USER", "MESSENGER", "DELEGATE", "AGENCY"]
}
"vat": 0.07
}

View file

@ -1,4 +1,5 @@
import { PayCondition, Prisma, Status } from "@prisma/client";
import config from "../config.json";
import {
Body,
Controller,
@ -63,6 +64,7 @@ type QuotationCreate = {
urgent?: boolean;
agentPrice?: boolean;
discount?: number;
productServiceList: {
serviceId?: string;
@ -74,12 +76,7 @@ type QuotationCreate = {
* @minimum 0
*/
discount?: number;
pricePerUnit?: number;
/**
* @maximum 1
* @minimum 0
*/
vat?: number;
workerIndex?: number[];
}[];
};
@ -122,6 +119,8 @@ type QuotationUpdate = {
urgent?: boolean;
discount?: number;
productServiceList?: {
serviceId?: string;
workId?: string;
@ -132,15 +131,12 @@ type QuotationUpdate = {
* @minimum 0
*/
discount: number;
pricePerUnit?: number;
/**
* @maximum 1
* @minimum 0
*/
vat?: number;
workerIndex?: number[];
}[];
};
const VAT_DEFAULT = config.vat;
const MANAGE_ROLES = [
"system",
"head_of_admin",
@ -150,7 +146,6 @@ const MANAGE_ROLES = [
"head_of_sale",
"sale",
];
const VAT_DEFAULT = 0.07;
function globalAllow(user: RequestWithUser["user"]) {
const allowList = ["system", "head_of_admin", "head_of_account", "head_of_sale"];
@ -322,28 +317,38 @@ export class QuotationController extends Controller {
update: { value: { increment: 1 } },
});
const list = body.productServiceList.map((v, i) => ({
order: i + 1,
productId: v.productId,
workId: v.workId,
serviceId: v.serviceId,
pricePerUnit:
product.find((p) => p.id === v.productId)?.[body.agentPrice ? "agentPrice" : "price"] ||
0,
amount: v.amount,
discount: v.discount || 0,
vat: v.vat || VAT_DEFAULT,
}));
const list = body.productServiceList.map((v, i) => {
const p = product.find((p) => p.id === v.productId)!;
const price = body.agentPrice ? p.agentPrice : p.price;
const pricePerUnit = p.vatIncluded ? precisionRound(price / 1 + VAT_DEFAULT) : price;
const vat = precisionRound(p.vatIncluded ? price - pricePerUnit : price * VAT_DEFAULT);
return {
order: i + 1,
productId: v.productId,
workId: v.workId,
serviceId: v.serviceId,
pricePerUnit:
product.find((p) => p.id === v.productId)?.[body.agentPrice ? "agentPrice" : "price"] ||
0,
amount: v.amount,
discount: v.discount || 0,
vat,
worker: {
create: sortedEmployeeId
.filter((_, i) => !v.workerIndex || i in v.workerIndex)
.map((employeeId) => ({ employeeId })),
},
};
});
const price = list.reduce(
(a, c) => {
const price = precisionRound(c.pricePerUnit * c.amount);
const discount = precisionRound(price - (c.discount || 0));
const vat = precisionRound((price - discount) * c.vat);
const multiply = precisionRound(c.pricePerUnit * c.amount);
a.totalPrice = precisionRound(a.totalPrice + price);
a.totalDiscount = precisionRound(a.totalDiscount + discount);
a.vat = precisionRound(a.vat + vat);
a.totalPrice = precisionRound(a.totalPrice + multiply);
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
a.vat = precisionRound(a.vat + c.vat);
a.finalPrice = precisionRound(a.totalPrice - a.totalDiscount + a.vat);
return a;
@ -352,7 +357,8 @@ export class QuotationController extends Controller {
totalPrice: 0,
totalDiscount: 0,
vat: 0,
finalPrice: 0,
discount: body.discount,
finalPrice: -(body.discount || 0),
},
);
@ -397,7 +403,9 @@ export class QuotationController extends Controller {
})),
},
},
productServiceList: { create: list },
productServiceList: {
create: list,
},
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
},
@ -517,28 +525,39 @@ export class QuotationController extends Controller {
}
}
const list = body.productServiceList?.map((v, i) => ({
order: i + 1,
productId: v.productId,
workId: v.workId,
serviceId: v.serviceId,
pricePerUnit:
product.find((p) => p.id === v.productId)?.[record.agentPrice ? "agentPrice" : "price"] ||
0,
amount: v.amount,
discount: v.discount || 0,
vat: v.vat || VAT_DEFAULT,
}));
const list = body.productServiceList?.map((v, i) => {
const p = product.find((p) => p.id === v.productId)!;
const price = record.agentPrice ? p.agentPrice : p.price;
const pricePerUnit = p.vatIncluded ? precisionRound(price / 1 + VAT_DEFAULT) : price;
const vat = precisionRound(p.vatIncluded ? price - pricePerUnit : price * VAT_DEFAULT);
return {
order: i + 1,
productId: v.productId,
workId: v.workId,
serviceId: v.serviceId,
pricePerUnit:
product.find((p) => p.id === v.productId)?.[
record.agentPrice ? "agentPrice" : "price"
] || 0,
amount: v.amount,
discount: v.discount || 0,
vat,
worker: {
create: sortedEmployeeId
.filter((_, i) => !v.workerIndex || i in v.workerIndex)
.map((employeeId) => ({ employeeId })),
},
};
});
const price = list?.reduce(
(a, c) => {
const price = precisionRound(c.pricePerUnit * c.amount);
const discount = precisionRound(price - (c.discount || 0));
const vat = precisionRound((price - discount) * c.vat);
const multiply = precisionRound(c.pricePerUnit * c.amount);
a.totalPrice = precisionRound(a.totalPrice + price);
a.totalDiscount = precisionRound(a.totalDiscount + discount);
a.vat = precisionRound(a.vat + vat);
a.totalPrice = precisionRound(a.totalPrice + multiply);
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
a.vat = precisionRound(a.vat + c.vat);
a.finalPrice = precisionRound(a.totalPrice - a.totalDiscount + a.vat);
return a;
@ -547,7 +566,8 @@ export class QuotationController extends Controller {
totalPrice: 0,
totalDiscount: 0,
vat: 0,
finalPrice: 0,
discount: body.discount,
finalPrice: -(body.discount || 0),
},
);