feat: add worker to quotation after accepted
This commit is contained in:
parent
98c42464eb
commit
d961d9c039
1 changed files with 85 additions and 104 deletions
|
|
@ -27,6 +27,8 @@ import { isUsedError, notFoundError, relationError } from "../utils/error";
|
||||||
import { precisionRound } from "../utils/arithmetic";
|
import { precisionRound } from "../utils/arithmetic";
|
||||||
import { queryOrNot } from "../utils/relation";
|
import { queryOrNot } from "../utils/relation";
|
||||||
import { deleteFile, fileLocation, getFile, getPresigned, listFile, setFile } from "../utils/minio";
|
import { deleteFile, fileLocation, getFile, getPresigned, listFile, setFile } from "../utils/minio";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import HttpStatus from "../interfaces/http-status";
|
||||||
|
|
||||||
type QuotationCreate = {
|
type QuotationCreate = {
|
||||||
registeredBranchId: string;
|
registeredBranchId: string;
|
||||||
|
|
@ -813,114 +815,77 @@ export class QuotationController extends Controller {
|
||||||
where: { id: quotationId },
|
where: { id: quotationId },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Post("{quotationId}/worker")
|
@Route("api/v1/quotation/{quotationId}")
|
||||||
@Security("keycloak", MANAGE_ROLES)
|
@Tags("Quotation")
|
||||||
|
export class QuotationActionController extends Controller {
|
||||||
|
@Post("add-worker")
|
||||||
async addWorker(
|
async addWorker(
|
||||||
@Request() req: RequestWithUser,
|
@Request() req: RequestWithUser,
|
||||||
@Path() quotationId: string,
|
@Path() quotationId: string,
|
||||||
@Body()
|
@Body()
|
||||||
body: {
|
body: {
|
||||||
workerId: string;
|
workerId: string;
|
||||||
productServiceListId: string[];
|
productServiceId: string[];
|
||||||
}[],
|
}[],
|
||||||
) {
|
) {
|
||||||
return await prisma.$transaction(async (tx) => {
|
const ids = {
|
||||||
let record = await tx.quotation.findFirst({
|
employee: body.map((v) => v.workerId),
|
||||||
|
productService: body
|
||||||
|
.flatMap((v) => v.productServiceId)
|
||||||
|
.filter((lhs, i, a) => a.findIndex((rhs) => lhs === rhs) === i),
|
||||||
|
};
|
||||||
|
|
||||||
|
const [quotation, employee, productService] = await prisma.$transaction(
|
||||||
|
async (tx) =>
|
||||||
|
await Promise.all([
|
||||||
|
tx.quotation.findFirst({
|
||||||
include: {
|
include: {
|
||||||
|
worker: true,
|
||||||
_count: {
|
_count: {
|
||||||
select: { paySplit: true },
|
select: {
|
||||||
},
|
|
||||||
customerBranch: {
|
|
||||||
include: {
|
|
||||||
customer: {
|
|
||||||
include: {
|
|
||||||
registeredBranch: { include: branchRelationPermInclude(req.user) },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
worker: true,
|
worker: true,
|
||||||
productServiceList: {
|
|
||||||
include: {
|
|
||||||
worker: true,
|
|
||||||
work: true,
|
|
||||||
service: true,
|
|
||||||
product: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
where: { id: quotationId },
|
where: { id: quotationId },
|
||||||
});
|
}),
|
||||||
|
tx.employee.findMany({
|
||||||
|
where: { id: { in: ids.employee } },
|
||||||
|
take: ids.employee.length + 1, // NOTE: Do not find further as it should be equal to input
|
||||||
|
}),
|
||||||
|
tx.quotationProductServiceList.findMany({
|
||||||
|
where: { id: { in: ids.productService }, quotationId },
|
||||||
|
take: ids.productService.length + 1, // NOTE: Do not find further as it should be equal to input
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
if (!record) throw notFoundError("Quotation");
|
if (!quotation) throw relationError("Quotation");
|
||||||
|
if (ids.employee.length !== employee.length) throw relationError("Worker");
|
||||||
let quotation = record;
|
if (ids.productService.length !== productService.length) throw relationError("Product");
|
||||||
|
if (quotation._count.worker >= (quotation.workerMax || 0)) {
|
||||||
const paymentSum = await tx.payment.aggregate({
|
throw new HttpError(
|
||||||
_sum: { amount: true },
|
HttpStatus.PRECONDITION_FAILED,
|
||||||
where: {
|
"Worker exceed current quotation max worker.",
|
||||||
invoice: {
|
"QuotationWorkerExceed",
|
||||||
quotationId: quotation.id,
|
);
|
||||||
payment: { paymentStatus: "PaymentSuccess" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
body = body.filter((a) => !quotation.worker.find((b) => b.employeeId === a.workerId));
|
|
||||||
if (!paymentSum._sum.amount) {
|
|
||||||
return await tx.quotation.update({
|
|
||||||
include: {
|
|
||||||
_count: {
|
|
||||||
select: { paySplit: true },
|
|
||||||
},
|
|
||||||
customerBranch: {
|
|
||||||
include: {
|
|
||||||
customer: {
|
|
||||||
include: {
|
|
||||||
registeredBranch: { include: branchRelationPermInclude(req.user) },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
worker: true,
|
|
||||||
productServiceList: {
|
|
||||||
include: {
|
|
||||||
worker: true,
|
|
||||||
work: true,
|
|
||||||
service: true,
|
|
||||||
product: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: { id: quotationId },
|
|
||||||
data: {
|
|
||||||
worker: {
|
|
||||||
createMany: {
|
|
||||||
data: body.map((v, i) => ({
|
|
||||||
employeeId: v.workerId,
|
|
||||||
no: quotation.worker.length + i + 1,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
productServiceList: {
|
|
||||||
update: quotation.productServiceList.map((a) => ({
|
|
||||||
where: { id: a.id },
|
|
||||||
data: {
|
|
||||||
worker: {
|
|
||||||
createMany: {
|
|
||||||
data: body
|
|
||||||
.filter((b) => b.productServiceListId.includes(a.id))
|
|
||||||
.map((val) => ({ employeeId: val.workerId })),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await prisma.$transaction(async (tx) => {
|
||||||
|
await tx.quotationProductServiceWorker.createMany({
|
||||||
|
data: body
|
||||||
|
.filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId))
|
||||||
|
.flatMap((lhs) =>
|
||||||
|
lhs.productServiceId.map((rhs) => ({
|
||||||
|
employeeId: lhs.workerId,
|
||||||
|
productServiceId: rhs,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
|
||||||
const current = new Date();
|
const current = new Date();
|
||||||
const year = `${current.getFullYear()}`.slice(-2).padStart(2, "0");
|
const year = `${current.getFullYear()}`.slice(-2).padStart(2, "0");
|
||||||
const month = `${current.getMonth() + 1}`.padStart(2, "0");
|
const month = `${current.getMonth() + 1}`.padStart(2, "0");
|
||||||
|
|
@ -935,22 +900,38 @@ export class QuotationController extends Controller {
|
||||||
},
|
},
|
||||||
update: { value: { increment: quotation.worker.length } },
|
update: { value: { increment: quotation.worker.length } },
|
||||||
});
|
});
|
||||||
|
console.log(quotation.worker);
|
||||||
await tx.quotation.update({
|
await tx.quotation.update({
|
||||||
where: { id: quotationId },
|
where: { id: quotationId },
|
||||||
data: {
|
data: {
|
||||||
requestData: {
|
worker: {
|
||||||
create: body.map((v, i) => ({
|
createMany: {
|
||||||
code: `TR${year}${month}${(lastRequest.value - quotation.worker.length + i + 1).toString().padStart(6, "0")}`,
|
data: body
|
||||||
|
.filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId))
|
||||||
|
.map((v, i) => ({
|
||||||
|
no: quotation._count.worker + i + 1,
|
||||||
employeeId: v.workerId,
|
employeeId: v.workerId,
|
||||||
requestWork: {
|
|
||||||
create: v.productServiceListId
|
|
||||||
.filter((a) => quotation.productServiceList.find((b) => a === b.id))
|
|
||||||
.map((v) => ({ productServiceId: v })),
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requestData:
|
||||||
|
quotation.quotationStatus === "PaymentInProcess" ||
|
||||||
|
quotation.quotationStatus === "PaymentSuccess"
|
||||||
|
? {
|
||||||
|
create: body
|
||||||
|
.filter(
|
||||||
|
(lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId),
|
||||||
|
)
|
||||||
|
.map((v, i) => ({
|
||||||
|
code: `TR${year}${month}${(lastRequest.value - quotation._count.worker + i + 1).toString().padStart(6, "0")}`,
|
||||||
|
employeeId: v.workerId,
|
||||||
|
requestWork: {
|
||||||
|
create: v.productServiceId.map((v) => ({ productServiceId: v })),
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue