2024-07-18 17:23:41 +07:00
|
|
|
import { PayCondition, Status } from "@prisma/client";
|
|
|
|
|
import {
|
|
|
|
|
Body,
|
|
|
|
|
Controller,
|
|
|
|
|
Delete,
|
|
|
|
|
Get,
|
|
|
|
|
Path,
|
|
|
|
|
Post,
|
|
|
|
|
Put,
|
|
|
|
|
Query,
|
|
|
|
|
Request,
|
|
|
|
|
Route,
|
|
|
|
|
Security,
|
|
|
|
|
Tags,
|
|
|
|
|
} from "tsoa";
|
|
|
|
|
import { RequestWithUser } from "../interfaces/user";
|
2024-07-19 10:41:37 +07:00
|
|
|
import prisma from "../db";
|
|
|
|
|
import HttpError from "../interfaces/http-error";
|
|
|
|
|
import HttpStatus from "../interfaces/http-status";
|
2024-07-18 17:23:41 +07:00
|
|
|
|
|
|
|
|
type QuotationCreate = {
|
|
|
|
|
status?: Status;
|
|
|
|
|
|
|
|
|
|
payCondition: PayCondition;
|
|
|
|
|
|
|
|
|
|
paySplitCount?: number;
|
|
|
|
|
paySplit?: Date[];
|
|
|
|
|
|
|
|
|
|
payBillDate?: number;
|
|
|
|
|
|
|
|
|
|
workerCount: number;
|
2024-07-19 10:41:37 +07:00
|
|
|
// EmployeeId or Create new employee
|
|
|
|
|
worker: (
|
|
|
|
|
| string
|
|
|
|
|
| {
|
|
|
|
|
dateOfBirth: Date;
|
|
|
|
|
gender: string;
|
|
|
|
|
nationality: string;
|
|
|
|
|
|
|
|
|
|
firstName: string;
|
|
|
|
|
firstNameEN: string;
|
|
|
|
|
lastName: string;
|
|
|
|
|
lastNameEN: string;
|
|
|
|
|
|
|
|
|
|
addressEN: string;
|
|
|
|
|
address: string;
|
|
|
|
|
zipCode: string;
|
|
|
|
|
|
|
|
|
|
passportType: string;
|
|
|
|
|
passportNumber: string;
|
|
|
|
|
passportIssueDate: Date;
|
|
|
|
|
passportExpiryDate: Date;
|
|
|
|
|
passportIssuingCountry: string;
|
|
|
|
|
passportIssuingPlace: string;
|
|
|
|
|
previousPassportReference?: string;
|
|
|
|
|
}
|
|
|
|
|
)[];
|
|
|
|
|
|
|
|
|
|
customerBranchId: string;
|
|
|
|
|
customerId: string;
|
2024-07-18 17:23:41 +07:00
|
|
|
|
|
|
|
|
urgent?: boolean;
|
|
|
|
|
|
|
|
|
|
service: {
|
|
|
|
|
id: string;
|
|
|
|
|
// Other fields will come from original data
|
2024-07-19 10:41:37 +07:00
|
|
|
work: {
|
2024-07-18 17:23:41 +07:00
|
|
|
// Name field will come from original data
|
|
|
|
|
product: {
|
|
|
|
|
id: string;
|
|
|
|
|
amount: number;
|
|
|
|
|
discount: number;
|
|
|
|
|
pricePerUnit: number;
|
|
|
|
|
}[];
|
|
|
|
|
}[];
|
2024-07-19 10:41:37 +07:00
|
|
|
}[];
|
2024-07-18 17:23:41 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type QuotationUpdate = {
|
|
|
|
|
status?: "ACTIVE" | "INACTIVE";
|
|
|
|
|
|
|
|
|
|
payCondition: PayCondition;
|
|
|
|
|
|
|
|
|
|
paySplitCount?: number;
|
|
|
|
|
paySplit?: Date[];
|
|
|
|
|
|
|
|
|
|
payBillDate?: number;
|
|
|
|
|
|
|
|
|
|
workerCount: number;
|
2024-07-19 10:41:37 +07:00
|
|
|
// EmployeeId or Create new employee
|
|
|
|
|
worker?: (
|
|
|
|
|
| string
|
|
|
|
|
| {
|
|
|
|
|
dateOfBirth: Date;
|
|
|
|
|
gender: string;
|
|
|
|
|
nationality: string;
|
|
|
|
|
|
|
|
|
|
firstName: string;
|
|
|
|
|
firstNameEN: string;
|
|
|
|
|
lastName: string;
|
|
|
|
|
lastNameEN: string;
|
|
|
|
|
|
|
|
|
|
addressEN: string;
|
|
|
|
|
address: string;
|
|
|
|
|
zipCode: string;
|
|
|
|
|
|
|
|
|
|
passportType: string;
|
|
|
|
|
passportNumber: string;
|
|
|
|
|
passportIssueDate: Date;
|
|
|
|
|
passportExpiryDate: Date;
|
|
|
|
|
passportIssuingCountry: string;
|
|
|
|
|
passportIssuingPlace: string;
|
|
|
|
|
previousPassportReference?: string;
|
|
|
|
|
}
|
|
|
|
|
)[];
|
|
|
|
|
|
|
|
|
|
customerBranchId: string;
|
|
|
|
|
customerId: string;
|
2024-07-18 17:23:41 +07:00
|
|
|
|
|
|
|
|
urgent?: boolean;
|
|
|
|
|
|
|
|
|
|
service: {
|
|
|
|
|
id: string;
|
|
|
|
|
// Other fields will come from original data
|
2024-07-19 10:41:37 +07:00
|
|
|
work: {
|
2024-07-18 17:23:41 +07:00
|
|
|
// Name field will come from original data
|
|
|
|
|
product: {
|
|
|
|
|
id: string;
|
|
|
|
|
amount: number;
|
|
|
|
|
discount: number;
|
|
|
|
|
pricePerUnit: number;
|
|
|
|
|
}[];
|
|
|
|
|
}[];
|
2024-07-19 10:41:37 +07:00
|
|
|
}[];
|
2024-07-18 17:23:41 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@Route("/api/v1/quotation")
|
|
|
|
|
@Tags("Quotation")
|
|
|
|
|
export class QuotationController extends Controller {
|
|
|
|
|
@Get("{quotationId}")
|
|
|
|
|
@Security("keycloak")
|
2024-07-19 10:41:37 +07:00
|
|
|
async getQuotationById(@Path() quotationId: string) {
|
|
|
|
|
const record = await prisma.quotation.findUnique({
|
|
|
|
|
include: {
|
|
|
|
|
worker: true,
|
|
|
|
|
service: {
|
|
|
|
|
include: {
|
|
|
|
|
_count: { select: { work: true } },
|
|
|
|
|
work: {
|
|
|
|
|
include: {
|
|
|
|
|
_count: { select: { productOnWork: true } },
|
|
|
|
|
productOnWork: {
|
|
|
|
|
include: { product: true },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
where: { id: quotationId },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!record) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "Quotation not found.", "quotationNotFound");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return record;
|
|
|
|
|
}
|
2024-07-18 17:23:41 +07:00
|
|
|
|
|
|
|
|
@Get()
|
|
|
|
|
@Security("keycloak")
|
|
|
|
|
async getQuotationList(@Query() page: number = 1, @Query() pageSize: number = 30) {}
|
|
|
|
|
|
|
|
|
|
@Post()
|
|
|
|
|
@Security("keycloak")
|
|
|
|
|
async createQuotation(@Request() req: RequestWithUser, @Body() body: QuotationCreate) {}
|
|
|
|
|
|
|
|
|
|
@Put("{quotationId}")
|
|
|
|
|
@Security("keycloak")
|
|
|
|
|
async editQuotation(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Path() quotationId: string,
|
|
|
|
|
@Body() body: QuotationUpdate,
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
@Delete("{quotationId}")
|
|
|
|
|
@Security("keycloak")
|
|
|
|
|
async deleteQuotationById(@Request() req: RequestWithUser, @Path() quotationId: string) {}
|
|
|
|
|
}
|