Merge branch 'develop'
This commit is contained in:
commit
06c54780d3
5 changed files with 146 additions and 16 deletions
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- Made the column `vatIncluded` on table `Product` required. This step will fail if there are existing NULL values in that column.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Product" ADD COLUMN "agentPriceCalcVat" BOOLEAN,
|
||||
ADD COLUMN "agentPriceVatIncluded" BOOLEAN,
|
||||
ADD COLUMN "serviceChargeCalcVat" BOOLEAN,
|
||||
ADD COLUMN "serviceChargeVatIncluded" BOOLEAN,
|
||||
ALTER COLUMN "vatIncluded" SET NOT NULL,
|
||||
ALTER COLUMN "vatIncluded" SET DEFAULT true;
|
||||
UPDATE "Product" SET "agentPriceCalcVat" = "Product"."calcVat" WHERE "agentPriceCalcVat" IS NULL;
|
||||
UPDATE "Product" SET "agentPriceVatIncluded" = "Product"."vatIncluded" WHERE "agentPriceVatIncluded" IS NULL;
|
||||
UPDATE "Product" SET "serviceChargeCalcVat" = "Product"."calcVat" WHERE "serviceChargeCalcVat" IS NULL;
|
||||
UPDATE "Product" SET "serviceChargeVatIncluded" = "Product"."vatIncluded" WHERE "serviceChargeVatIncluded" IS NULL;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "Product" ALTER COLUMN "agentPriceCalcVat" SET DEFAULT true,
|
||||
ALTER COLUMN "agentPriceVatIncluded" SET DEFAULT true,
|
||||
ALTER COLUMN "serviceChargeCalcVat" SET DEFAULT true,
|
||||
ALTER COLUMN "serviceChargeVatIncluded" SET DEFAULT true;
|
||||
|
|
@ -1103,10 +1103,16 @@ model Product {
|
|||
price Float
|
||||
agentPrice Float
|
||||
serviceCharge Float
|
||||
vatIncluded Boolean?
|
||||
expenseType String?
|
||||
|
||||
calcVat Boolean @default(true)
|
||||
vatIncluded Boolean @default(true)
|
||||
calcVat Boolean @default(true)
|
||||
|
||||
agentPriceVatIncluded Boolean? @default(true)
|
||||
agentPriceCalcVat Boolean? @default(true)
|
||||
|
||||
serviceChargeVatIncluded Boolean? @default(true)
|
||||
serviceChargeCalcVat Boolean? @default(true)
|
||||
|
||||
status Status @default(CREATED)
|
||||
statusOrder Int @default(0)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ type ProductCreate = {
|
|||
serviceCharge: number;
|
||||
vatIncluded?: boolean;
|
||||
calcVat?: boolean;
|
||||
agentPriceVatIncluded?: boolean;
|
||||
agentPriceCalcVat?: boolean;
|
||||
serviceChargeVatIncluded?: boolean;
|
||||
serviceChargeCalcVat?: boolean;
|
||||
expenseType?: string;
|
||||
selectedImage?: string;
|
||||
shared?: boolean;
|
||||
|
|
@ -77,6 +81,10 @@ type ProductUpdate = {
|
|||
remark?: string;
|
||||
vatIncluded?: boolean;
|
||||
calcVat?: boolean;
|
||||
agentPriceVatIncluded?: boolean;
|
||||
agentPriceCalcVat?: boolean;
|
||||
serviceChargeVatIncluded?: boolean;
|
||||
serviceChargeCalcVat?: boolean;
|
||||
expenseType?: string;
|
||||
selectedImage?: string;
|
||||
shared?: boolean;
|
||||
|
|
|
|||
|
|
@ -478,9 +478,11 @@ export class QuotationController extends Controller {
|
|||
const list = body.productServiceList.map((v, i) => {
|
||||
const p = product.find((p) => p.id === v.productId)!;
|
||||
|
||||
const vatIncluded = body.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
||||
|
||||
const originalPrice = body.agentPrice ? p.agentPrice : p.price;
|
||||
const finalPriceWithVat = precisionRound(
|
||||
originalPrice + (p.vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||
);
|
||||
|
||||
const price = finalPriceWithVat;
|
||||
|
|
@ -743,9 +745,11 @@ export class QuotationController extends Controller {
|
|||
const list = body.productServiceList?.map((v, i) => {
|
||||
const p = product.find((p) => p.id === v.productId)!;
|
||||
|
||||
const vatIncluded = record.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
||||
|
||||
const originalPrice = record.agentPrice ? p.agentPrice : p.price;
|
||||
const finalPriceWithVat = precisionRound(
|
||||
originalPrice + (p.vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||
);
|
||||
|
||||
const price = finalPriceWithVat;
|
||||
|
|
@ -919,14 +923,63 @@ export class QuotationActionController extends Controller {
|
|||
@Request() req: RequestWithUser,
|
||||
@Path() quotationId: string,
|
||||
@Body()
|
||||
body: {
|
||||
workerId: string;
|
||||
productServiceId: string[];
|
||||
}[],
|
||||
body: (
|
||||
| {
|
||||
workerId: string;
|
||||
productServiceId: string[];
|
||||
}
|
||||
| {
|
||||
workerData: {
|
||||
dateOfBirth: Date;
|
||||
gender: string;
|
||||
nationality: string;
|
||||
namePrefix?: string;
|
||||
firstName: string;
|
||||
firstNameEN: string;
|
||||
middleName?: string;
|
||||
middleNameEN?: string;
|
||||
lastName: string;
|
||||
lastNameEN: string;
|
||||
};
|
||||
productServiceId: string[];
|
||||
}
|
||||
)[],
|
||||
) {
|
||||
const { existsEmployee, newEmployee } = body.reduce<{
|
||||
existsEmployee: {
|
||||
workerId: string;
|
||||
productServiceId: string[];
|
||||
}[];
|
||||
newEmployee: {
|
||||
workerData: {
|
||||
dateOfBirth: Date;
|
||||
gender: string;
|
||||
nationality: string;
|
||||
namePrefix?: string;
|
||||
firstName: string;
|
||||
firstNameEN: string;
|
||||
middleName?: string;
|
||||
middleNameEN?: string;
|
||||
lastName: string;
|
||||
lastNameEN: string;
|
||||
};
|
||||
productServiceId: string[];
|
||||
}[];
|
||||
}>(
|
||||
(acc, current) => {
|
||||
if ("workerId" in current) {
|
||||
acc.existsEmployee.push(current);
|
||||
} else {
|
||||
acc.newEmployee.push(current);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{ existsEmployee: [], newEmployee: [] },
|
||||
);
|
||||
|
||||
const ids = {
|
||||
employee: body.map((v) => v.workerId),
|
||||
productService: body
|
||||
employee: existsEmployee.map((v) => v.workerId),
|
||||
productService: existsEmployee
|
||||
.flatMap((v) => v.productServiceId)
|
||||
.filter((lhs, i, a) => a.findIndex((rhs) => lhs === rhs) === i),
|
||||
};
|
||||
|
|
@ -936,6 +989,7 @@ export class QuotationActionController extends Controller {
|
|||
await Promise.all([
|
||||
tx.quotation.findFirst({
|
||||
include: {
|
||||
customerBranch: true,
|
||||
worker: true,
|
||||
_count: {
|
||||
select: {
|
||||
|
|
@ -961,11 +1015,13 @@ export class QuotationActionController extends Controller {
|
|||
if (ids.productService.length !== productService.length) throw relationError("Product");
|
||||
if (
|
||||
quotation._count.worker +
|
||||
body.filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId))
|
||||
.length >
|
||||
existsEmployee.filter(
|
||||
(lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId),
|
||||
).length +
|
||||
newEmployee.length >
|
||||
(quotation.workerMax || 0)
|
||||
) {
|
||||
if (body.length === 0) return;
|
||||
if (existsEmployee.length === 0) return;
|
||||
throw new HttpError(
|
||||
HttpStatus.PRECONDITION_FAILED,
|
||||
"Worker exceed current quotation max worker.",
|
||||
|
|
@ -974,8 +1030,46 @@ export class QuotationActionController extends Controller {
|
|||
}
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
const customerBranch = quotation.customerBranch;
|
||||
const lastEmployee = await tx.runningNo.upsert({
|
||||
where: {
|
||||
key: `EMPLOYEE_${customerBranch.id}-${`${new Date().getFullYear()}`.slice(-2).padStart(2, "0")}`,
|
||||
},
|
||||
create: {
|
||||
key: `EMPLOYEE_${customerBranch.id}-${`${new Date().getFullYear()}`.slice(-2).padStart(2, "0")}`,
|
||||
value: newEmployee.length,
|
||||
},
|
||||
update: { value: { increment: newEmployee.length } },
|
||||
});
|
||||
|
||||
const newEmployeeWithId = await Promise.all(
|
||||
newEmployee.map(async (v, i) => {
|
||||
const data = await tx.employee.create({
|
||||
data: {
|
||||
...v.workerData,
|
||||
code: `${customerBranch.code}-${`${new Date().getFullYear()}`.slice(-2).padStart(2, "0")}${`${lastEmployee.value - nonExistEmployee.length + i + 1}`.padStart(7, "0")}`,
|
||||
customerBranchId: customerBranch.id,
|
||||
},
|
||||
});
|
||||
|
||||
return { workerId: data.id, productServiceId: v.productServiceId };
|
||||
}),
|
||||
);
|
||||
|
||||
const rearrange: typeof existsEmployee = [];
|
||||
|
||||
while (body.length > 0) {
|
||||
const item = body.shift();
|
||||
if (item && "workerId" in item) {
|
||||
rearrange.push(item);
|
||||
} else {
|
||||
const popNew = newEmployeeWithId.shift();
|
||||
popNew && rearrange.push(popNew);
|
||||
}
|
||||
}
|
||||
|
||||
await tx.quotationProductServiceWorker.createMany({
|
||||
data: body
|
||||
data: existsEmployee
|
||||
.filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId))
|
||||
.flatMap((lhs) =>
|
||||
lhs.productServiceId.map((rhs) => ({
|
||||
|
|
@ -1006,7 +1100,7 @@ export class QuotationActionController extends Controller {
|
|||
quotationStatus: QuotationStatus.PaymentSuccess, // NOTE: change back if already complete or canceled
|
||||
worker: {
|
||||
createMany: {
|
||||
data: body
|
||||
data: rearrange
|
||||
.filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId))
|
||||
.map((v, i) => ({
|
||||
no: quotation._count.worker + i + 1,
|
||||
|
|
@ -1018,7 +1112,7 @@ export class QuotationActionController extends Controller {
|
|||
quotation.quotationStatus === "PaymentInProcess" ||
|
||||
quotation.quotationStatus === "PaymentSuccess"
|
||||
? {
|
||||
create: body
|
||||
create: rearrange
|
||||
.filter(
|
||||
(lhs) =>
|
||||
!quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId) &&
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue