From 93d2e1f4227e41b1a0a1b27ef2fb70e273654bde Mon Sep 17 00:00:00 2001 From: Rizki Date: Tue, 27 Jan 2026 18:02:18 +0700 Subject: [PATCH] add entity for tender --- .../procurement_checklist_payment.ts | 81 +++++++ .../procurement_checklist_payment_approval.ts | 32 +++ .../procurement_checklist_payment_document.ts | 20 ++ .../procurement_checklist_payment_item.ts | 37 +++ src/entity/procurement/procurement_tender.ts | 229 ++++++++++++++++++ src/schema/procurement.ts | 5 + src/types/procurement.ts | 41 ++++ 7 files changed, 445 insertions(+) create mode 100644 src/entity/procurement/procurement_checklist_payment.ts create mode 100644 src/entity/procurement/procurement_checklist_payment_approval.ts create mode 100644 src/entity/procurement/procurement_checklist_payment_document.ts create mode 100644 src/entity/procurement/procurement_checklist_payment_item.ts create mode 100644 src/entity/procurement/procurement_tender.ts diff --git a/src/entity/procurement/procurement_checklist_payment.ts b/src/entity/procurement/procurement_checklist_payment.ts new file mode 100644 index 0000000..c90a66b --- /dev/null +++ b/src/entity/procurement/procurement_checklist_payment.ts @@ -0,0 +1,81 @@ +import { Column, CreateDateColumn, DeleteDateColumn, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm"; +import { HrmsDepartment } from "../hrms/hrms_department"; +import { ProcurementChecklistPaymentItem } from "./procurement_checklist_payment_item"; +import { ProcurementChecklistPaymentApproval } from "./procurement_checklist_payment_approval"; +import { FinanceFundingSource } from "../finance/finance_funding_sources"; +import { FinanceAtividade } from "../finance/finance_atividade"; +import { FinanceSubBudgetLine } from "../finance/fincance_sub_budget_lines"; +import { ProcurementChecklistPaymentStatus, ProcurementChecklistPaymentType } from "../../types/procurement"; +import { ProcurementTender } from "./procurement_tender"; + +@Entity("procurement_checklist_payment", { schema: "procurement" }) +export class ProcurementChecklistPayment { + @PrimaryGeneratedColumn("uuid") + id: string; + + @ManyToOne(() => ProcurementTender, (tender) => tender.checklist_payment, { onDelete: "CASCADE" }) + tender: ProcurementTender; + + @Column({ + unique: false, + length: 128, + }) + type: ProcurementChecklistPaymentType; + + @Column({ + unique: true, + length: 128, + }) + code: string; + + @Column({ + nullable: false, + }) + checklist_payment_at: Date; + + @ManyToOne(() => FinanceFundingSource, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + funding_source: FinanceFundingSource; + + @ManyToOne(() => HrmsDepartment, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + department: HrmsDepartment; + + @ManyToOne(() => FinanceAtividade, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + activity: FinanceAtividade; + + @ManyToOne(() => FinanceSubBudgetLine, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + sub_budget_line: FinanceSubBudgetLine; + + @OneToMany(() => ProcurementChecklistPaymentItem, (item) => item.payment, { cascade: true }) + items: ProcurementChecklistPaymentItem[]; + + @OneToMany(() => ProcurementChecklistPaymentApproval, (approval) => approval.payment, { cascade: true }) + approvals: ProcurementChecklistPaymentApproval[]; + + @Column({ nullable: false }) + status: ProcurementChecklistPaymentStatus; + + @Column() + @CreateDateColumn() + created_at: Date; + + @Column({ nullable: true, length: 256 }) + created_by: string; + + @Column({ nullable: true }) + @UpdateDateColumn() + updated_at: Date; + + @Column({ nullable: true, length: 256 }) + updated_by: string; + + @Column({ nullable: true }) + @DeleteDateColumn() + deleted_at: Date; + + @Column({ nullable: true, length: 256 }) + deleted_by: string; +} diff --git a/src/entity/procurement/procurement_checklist_payment_approval.ts b/src/entity/procurement/procurement_checklist_payment_approval.ts new file mode 100644 index 0000000..b857d60 --- /dev/null +++ b/src/entity/procurement/procurement_checklist_payment_approval.ts @@ -0,0 +1,32 @@ +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { ProcurementChecklistPayment } from "./procurement_checklist_payment"; +import { ProcurementChecklistPaymentApprovalRole } from "../../types/procurement"; +import { HrmsEmployee } from "../hrms/hrms_employee"; + +@Entity("procurement_checklist_payment_approval", { schema: "procurement" }) +export class ProcurementChecklistPaymentApproval { + @PrimaryGeneratedColumn("uuid") + id: string; + + @ManyToOne(() => ProcurementChecklistPayment, (payment) => payment.approvals, { onDelete: "CASCADE" }) + payment: ProcurementChecklistPayment; + + @Column({ type: "enum", enum: ProcurementChecklistPaymentApprovalRole }) + role: ProcurementChecklistPaymentApprovalRole; + + @ManyToOne(() => HrmsEmployee, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + employee: HrmsEmployee; + + @Column() + name: string; + + @Column({ nullable: true }) + position: string; + + @Column({ type: "date", nullable: true }) + signed_date: Date; + + @Column({ nullable: true, default: false }) + is_signed: boolean; +} diff --git a/src/entity/procurement/procurement_checklist_payment_document.ts b/src/entity/procurement/procurement_checklist_payment_document.ts new file mode 100644 index 0000000..48ebeb3 --- /dev/null +++ b/src/entity/procurement/procurement_checklist_payment_document.ts @@ -0,0 +1,20 @@ +import { Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { ProcurementChecklistPaymentItem } from "./procurement_checklist_payment_item"; + +@Entity("procurement_checklist_payment_document", { schema: "procurement" }) +export class ProcurementChecklistPaymentDocument { + @PrimaryGeneratedColumn("uuid") + id: string; + + @ManyToOne(() => ProcurementChecklistPaymentItem, (item) => item.documents, { onDelete: "CASCADE" }) + checklist_item: ProcurementChecklistPaymentItem; + + @Column({ nullable: true }) + reference_id: string; + + @Column({ nullable: true }) + document_number: string; + + @CreateDateColumn() + created_at: Date; +} diff --git a/src/entity/procurement/procurement_checklist_payment_item.ts b/src/entity/procurement/procurement_checklist_payment_item.ts new file mode 100644 index 0000000..1b568c3 --- /dev/null +++ b/src/entity/procurement/procurement_checklist_payment_item.ts @@ -0,0 +1,37 @@ +import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { ProcurementChecklistPayment } from "./procurement_checklist_payment"; +import { ProcurementChecklistPaymentItemType } from "../../types/procurement"; +import { ProcurementChecklistPaymentDocument } from "./procurement_checklist_payment_document"; + +@Entity("procurement_checklist_payment_item", { schema: "procurement" }) +export class ProcurementChecklistPaymentItem { + @PrimaryGeneratedColumn("uuid") + id: string; + + @ManyToOne(() => ProcurementChecklistPayment, (payment) => payment.items, { onDelete: "CASCADE" }) + payment: ProcurementChecklistPayment; + + @Column({ type: "enum", enum: ProcurementChecklistPaymentItemType }) + type: ProcurementChecklistPaymentItemType; + + @Column({ default: false }) + is_checked: boolean; + + @Column({ type: "date", nullable: true }) + file_date: Date; + + @Column({ + nullable: true, + type: "float8", + }) + fund: number; + + @Column({ length: 128, nullable: true }) + document_number: string; + + @Column({ nullable: true }) + reference_id: string; + + @OneToMany(() => ProcurementChecklistPaymentDocument, (doc) => doc.checklist_item, { cascade: true }) + documents: ProcurementChecklistPaymentDocument[]; +} diff --git a/src/entity/procurement/procurement_tender.ts b/src/entity/procurement/procurement_tender.ts new file mode 100644 index 0000000..46a2761 --- /dev/null +++ b/src/entity/procurement/procurement_tender.ts @@ -0,0 +1,229 @@ +import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, DeleteDateColumn, ManyToOne, JoinColumn, OneToMany } from "typeorm"; +import { HrmsDepartment } from "../hrms/hrms_department"; +import { Status } from "../../types/status"; +import { FinanceCpv } from "../finance/finance_cpvs"; +import { ProcurementTenderStatus } from "../../types/procurement"; +import { ProcurementVendor } from "./procurement_vendor"; +import { ProcurementChecklistPayment } from "./procurement_checklist_payment"; + +@Entity("procurement_tenders", { schema: "procurement" }) +export class ProcurementTender { + @PrimaryGeneratedColumn("uuid") + id: string; + + // ========================= + // GENERAL INFORMATION + // ========================= + + @ManyToOne(() => HrmsDepartment, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + department: HrmsDepartment; + + @ManyToOne(() => FinanceCpv, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + cpv: FinanceCpv; + + // ========================= + // TENDER INFORMATION + // ========================= + + @Column({ length: 64 }) + tender_number: string; // 123/ANTL/2025/011 + + @Column({ length: 256 }) + tender_name: string; + + @Column({ length: 32 }) + tender_type: string; // Tender / RFQ / etc + + @Column({ type: "float8", nullable: true }) + planning_price: number; + + @Column({ type: "float8", nullable: true }) + realization_price: number; + + @ManyToOne(() => ProcurementVendor, { onDelete: "NO ACTION", nullable: true }) + @JoinColumn() + vendor: ProcurementVendor; + + @Column({ type: "date", nullable: true }) + start_date: Date; + + @Column({ type: "date", nullable: true }) + target_complete_date: Date; + + @Column({ length: 32 }) + status: ProcurementTenderStatus; // On Going, Completed, Cancelled + + // ========================= + // UPLOAD DOCUMENTS (CORE) + // ========================= + + // Pedido Pagamentu (PR) + @Column({ length: 256, nullable: true }) + pr_file_url: string; + + @Column({ type: "date", nullable: true }) + pr_file_date: Date; + + @Column({ length: 64, nullable: true }) + pr_number: string; + + // CPV / PR + @Column({ length: 256, nullable: true }) + cpv_pr_file_url: string; + + @Column({ type: "date", nullable: true }) + cpv_pr_file_date: Date; + + @Column({ length: 64, nullable: true }) + cpv_pr_number: string; + + // Obrigasan + @Column({ length: 256, nullable: true }) + obrigasan_file_url: string; + + @Column({ type: "date", nullable: true }) + obrigasan_file_date: Date; + + @Column({ length: 64, nullable: true }) + obrigasan_number: string; + + // PO + @Column({ length: 256, nullable: true }) + po_file_url: string; + + @Column({ type: "date", nullable: true }) + po_file_date: Date; + + @Column({ length: 64, nullable: true }) + po_number: string; + + // Factura + @Column({ length: 256, nullable: true }) + facture_file_url: string; + + @Column({ type: "date", nullable: true }) + facture_file_date: Date; + + @Column({ length: 64, nullable: true }) + facture_number: string; + + // R&I Report + @Column({ length: 256, nullable: true }) + ri_report_file_url: string; + + @Column({ type: "date", nullable: true }) + ri_report_file_date: Date; + + @Column({ length: 64, nullable: true }) + ri_report_number: string; + + // Certificate Payment + @Column({ length: 256, nullable: true }) + certificate_payment_file_url: string; + + @Column({ type: "date", nullable: true }) + certificate_payment_file_date: Date; + + @Column({ length: 64, nullable: true }) + certificate_payment_number: string; + + // Contract + @Column({ length: 256, nullable: true }) + contract_file_url: string; + + @Column({ type: "date", nullable: true }) + contract_file_date: Date; + + @Column({ length: 64, nullable: true }) + contract_number: string; + + // Recommendation Maintenance + @Column({ length: 256, nullable: true }) + recommendation_file_url: string; + + @Column({ type: "date", nullable: true }) + recommendation_file_date: Date; + + @Column({ length: 64, nullable: true }) + recommendation_number: string; + + // Service Report + @Column({ length: 256, nullable: true }) + service_report_file_url: string; + + @Column({ type: "date", nullable: true }) + service_report_file_date: Date; + + @Column({ length: 64, nullable: true }) + service_report_number: string; + + // ========================= + // OTHER DOCUMENT (3 ITEMS) + // ========================= + + @Column({ length: 128, nullable: true }) + other_doc1_label: string; + + @Column({ length: 256, nullable: true }) + other_doc1_file_url: string; + + @Column({ type: "date", nullable: true }) + other_doc1_file_date: Date; + + @Column({ length: 64, nullable: true }) + other_doc1_number: string; + + @Column({ length: 128, nullable: true }) + other_doc2_label: string; + + @Column({ length: 256, nullable: true }) + other_doc2_file_url: string; + + @Column({ type: "date", nullable: true }) + other_doc2_file_date: Date; + + @Column({ length: 64, nullable: true }) + other_doc2_number: string; + + @Column({ length: 128, nullable: true }) + other_doc3_label: string; + + @Column({ length: 256, nullable: true }) + other_doc3_file_url: string; + + @Column({ type: "date", nullable: true }) + other_doc3_file_date: Date; + + @Column({ length: 64, nullable: true }) + other_doc3_number: string; + + // ========================= + // CHECKLIST PAAMENTO + // ========================= + @OneToMany(() => ProcurementChecklistPayment, (item) => item.tender, { cascade: true }) + checklist_payment: ProcurementChecklistPayment; + + // ========================= + // AUDIT + // ========================= + + @CreateDateColumn() + created_at: Date; + + @Column({ nullable: true, length: 256 }) + created_by: string; + + @UpdateDateColumn({ nullable: true }) + updated_at: Date; + + @Column({ nullable: true, length: 256 }) + updated_by: string; + + @DeleteDateColumn({ nullable: true }) + deleted_at: Date; + + @Column({ nullable: true, length: 256 }) + deleted_by: string; +} diff --git a/src/schema/procurement.ts b/src/schema/procurement.ts index 50cc349..092d340 100644 --- a/src/schema/procurement.ts +++ b/src/schema/procurement.ts @@ -1,5 +1,10 @@ export * from "../entity/procurement/procurement_category"; export * from "../entity/procurement/procurement_vendor"; export * from "../entity/procurement/procurement_project_yearly"; +export * from "../entity/procurement/procurement_tender"; +export * from "../entity/procurement/procurement_checklist_payment"; +export * from "../entity/procurement/procurement_checklist_payment_item"; +export * from "../entity/procurement/procurement_checklist_payment_document"; +export * from "../entity/procurement/procurement_checklist_payment_approval"; export * from "../types/procurement"; diff --git a/src/types/procurement.ts b/src/types/procurement.ts index be8521b..b5a9689 100644 --- a/src/types/procurement.ts +++ b/src/types/procurement.ts @@ -20,3 +20,44 @@ export enum ProcurementMethod { NCB = "NCB", ICB = "ICB", } + +export enum ProcurementTenderStatus { + ON_GOING = "ON_GOING", + COMPLETED = "COMPLETED", + CANCELLED = "CANCELLED", +} + +export enum ProcurementChecklistPaymentItemType { + ADVANCE_FUND = "advance_fund", + FCP_CPV = "fcp_cpv", + PRT = "prt", + PAYMENT_ORDER = "payment_order", + OBLIGATION = "obligation", + PAYMENT_REQUEST = "payment_request", + CHEQUE = "cheque", + INVOICE = "invoice", + ASSET_REGISTRATION = "asset_registration", + AND_RECOMMENDATION = "and_recomendation", + SERVICE_REPORT = "service_report", + FINANCE_CODE = "finance_code", + OTHER_DOCUMENT = "other_document", +} + +export enum ProcurementChecklistPaymentApprovalRole { + PREPARER = "preparer", + VERIFIER = "verifier", + APPROVER = "approver", +} + +export enum ProcurementChecklistPaymentStatus { + DRAFT = "draft", + PENDING_VERIFY = "pending_verifier", + PENDING_APPROVE = "pending_approver", + SUCCESS = "success", + REJECTED = "rejected", +} + +export enum ProcurementChecklistPaymentType { + SALARY_PAYMENT = "salary_payment", + DIRECT_PAYMENT = "direct_payment", +}