petty cash

This commit is contained in:
Narul Hidayah
2026-01-27 14:49:50 +07:00
11 changed files with 556 additions and 1 deletions

View File

@ -0,0 +1,78 @@
import { Column, CreateDateColumn, DeleteDateColumn, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { FinanceSubBudgetLine } from "./fincance_sub_budget_lines";
import { FinanceFundingSource } from "./finance_funding_sources";
import { FinanceAtividade } from "./finance_atividade";
import { FinanceBudgetLine } from "./fincance_budget_lines";
import { HrmsDepartment } from "../hrms/hrms_department";
import { FinanceChecklistPaymentItem } from "./finance_checklist_payment_item";
import { FinanceChecklistPaymentApproval } from "./finance_checklist_payment_approval";
import { FinanceChecklistPaymentStatus, FinanceChecklistPaymentType } from "../../types/finance";
@Entity("finance_checklist_payment", { schema: "finances" })
export class FinanceChecklistPayment {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({
unique: false,
length: 128,
})
type: FinanceChecklistPaymentType;
@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(() => FinanceChecklistPaymentItem, (item) => item.payment, { cascade: true })
items: FinanceChecklistPaymentItem[];
@OneToMany(() => FinanceChecklistPaymentApproval, (approval) => approval.payment, { cascade: true })
approvals: FinanceChecklistPaymentApproval[];
@Column({ nullable: false })
status: FinanceChecklistPaymentStatus;
@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;
}

View File

@ -0,0 +1,32 @@
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { FinanceChecklistPayment } from "./finance_checklist_payment";
import { FinanceChecklistPaymentApprovalRole } from "../../types/finance";
import { HrmsEmployee } from "../hrms/hrms_employee";
@Entity("finance_checklist_payment_approval", { schema: "finances" })
export class FinanceChecklistPaymentApproval {
@PrimaryGeneratedColumn("uuid")
id: string;
@ManyToOne(() => FinanceChecklistPayment, (payment) => payment.approvals, { onDelete: "CASCADE" })
payment: FinanceChecklistPayment;
@Column({ type: "enum", enum: FinanceChecklistPaymentApprovalRole })
role: FinanceChecklistPaymentApprovalRole;
@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;
}

View File

@ -0,0 +1,20 @@
import { Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { FinanceChecklistPaymentItem } from "./finance_checklist_payment_item";
@Entity("finance_checklist_payment_document", { schema: "finances" })
export class FinanceChecklistPaymentDocument {
@PrimaryGeneratedColumn("uuid")
id: string;
@ManyToOne(() => FinanceChecklistPaymentItem, (item) => item.documents, { onDelete: "CASCADE" })
checklist_item: FinanceChecklistPaymentItem;
@Column({ nullable: true })
reference_id: string;
@Column({ nullable: true })
document_number: string;
@CreateDateColumn()
created_at: Date;
}

View File

@ -0,0 +1,37 @@
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { FinanceChecklistPayment } from "./finance_checklist_payment";
import { FinanceChecklistPaymentItemType } from "../../types/finance";
import { FinanceChecklistPaymentDocument } from "./finance_checklist_payment_document";
@Entity("finance_checklist_payment_item", { schema: "finances" })
export class FinanceChecklistPaymentItem {
@PrimaryGeneratedColumn("uuid")
id: string;
@ManyToOne(() => FinanceChecklistPayment, (payment) => payment.items, { onDelete: "CASCADE" })
payment: FinanceChecklistPayment;
@Column({ type: "enum", enum: FinanceChecklistPaymentItemType })
type: FinanceChecklistPaymentItemType;
@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(() => FinanceChecklistPaymentDocument, (doc) => doc.checklist_item, { cascade: true })
documents: FinanceChecklistPaymentDocument[];
}

View File

@ -0,0 +1,57 @@
import { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { FinanceCpv } from "./finance_cpvs";
import { FinancePaymentOrder } from "./finance_payment_orders";
@Entity("finance_petty_cash_credits", { schema: "finances" })
@Index("UQ_finance_petty_cash_credits_cpv", ["cpvId"], { unique: true }) // Ensure CPV can only be used once for topup
export class FinancePettyCashCredit {
@PrimaryGeneratedColumn("uuid")
id: string;
@ManyToOne(() => FinanceCpv, { onDelete: "NO ACTION", nullable: false })
@JoinColumn({ name: "cpvId" })
cpv: FinanceCpv;
@ManyToOne(() => FinancePaymentOrder, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
payment_order: FinancePaymentOrder; // Order Pagamento from CPV
@Column({
nullable: false,
type: "float8",
})
amount: number; // Amount from CPV
@Column({
type: "text",
nullable: true,
})
amount_words: string;
@Column({
nullable: true,
type: "text",
})
description: string;
@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;
}

View File

@ -0,0 +1,117 @@
import { Column, CreateDateColumn, DeleteDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { FinanceAgencia } from "./finance_agencia";
import { FinanceAtividade } from "./finance_atividade";
import { FinanceSubBudgetLine } from "./fincance_sub_budget_lines";
import { FinanceLocalizacao } from "./finance_localizacao";
import { HrmsEmployee } from "../hrms/hrms_employee";
@Entity("finance_petty_cash_expenses", { schema: "finances" })
export class FinancePettyCashExpense {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({
nullable: false,
unique: true,
length: 128,
})
code: string; // Voucher code (e.g., "2025-0001/ANATL,E.P./03")
@Column({
nullable: false,
})
expense_date: Date; // Date of expense
@ManyToOne(() => FinanceAgencia, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
division_classification: FinanceAgencia; // Division Classification
@ManyToOne(() => FinanceAtividade, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
activity_classification: FinanceAtividade; // Activity Classification
@ManyToOne(() => FinanceSubBudgetLine, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
sub_rubric_code: FinanceSubBudgetLine; // Sub Rubric Code
@Column({
nullable: true,
length: 255,
})
paid_to: string; // Paid To/For
@Column({
nullable: false,
type: "float8",
})
total_amount: number; // Total Amount
@Column({
type: "text",
nullable: true,
})
amount_in_words: string; // Amount in Words
@Column({
type: "text",
nullable: true,
})
description: string; // Description of expense
@ManyToOne(() => HrmsEmployee, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
authorizing_officer: HrmsEmployee; // Authorizing Officer
@ManyToOne(() => HrmsEmployee, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
finance_officer: HrmsEmployee; // Finance Officer
@Column({
type: "text",
nullable: true,
})
acknowledgement: string; // Acknowledgement text
@Column({
nullable: true,
length: 255,
})
acknowledged_by_name: string; // Name of person acknowledging
@ManyToOne(() => FinanceLocalizacao, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
location: FinanceLocalizacao; // Location Code
@Column({
nullable: true,
length: 64,
})
document_number: string; // No. Doc. (e.g., "01", "02", "03")
@Column({
type: "text",
nullable: true,
})
observation: string; // Observation/Notes
@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;
}

View File

@ -0,0 +1,61 @@
import { Column, CreateDateColumn, DeleteDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { Status } from "../../types/status";
@Entity("finance_petty_cash_pockets", { schema: "finances" })
export class FinancePettyCashPocket {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({
nullable: false,
unique: true,
length: 128,
})
code: string;
@Column({
nullable: false,
length: 255,
})
name: string;
@Column({
nullable: true,
type: "text",
})
description: string;
@Column({
nullable: false,
type: "float8",
default: 0,
})
balance: number; // Current balance of the petty cash pocket
@Column({
nullable: false,
length: 64,
})
status: Status;
@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;
}

View File

@ -0,0 +1,114 @@
import { Column, CreateDateColumn, DeleteDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { FinancePettyCashCredit } from "./finance_petty_cash_credits";
import { FinancePettyCashExpense } from "./finance_petty_cash_expenses";
import { FinanceAgencia } from "./finance_agencia";
import { FinanceAtividade } from "./finance_atividade";
import { FinanceSubBudgetLine } from "./fincance_sub_budget_lines";
import { FinanceLocalizacao } from "./finance_localizacao";
import { PettyCashTransactionType } from "../../types/finance";
@Entity("finance_petty_cash_transactions", { schema: "finances" })
export class FinancePettyCashTransaction {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({
nullable: false,
})
transaction_date: Date; // Transaction date
@Column({
nullable: false,
length: 128,
})
type: PettyCashTransactionType; // credit or expense
@ManyToOne(() => FinancePettyCashCredit, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
credit: FinancePettyCashCredit; // Reference to credit if type is credit
@ManyToOne(() => FinancePettyCashExpense, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
expense: FinancePettyCashExpense; // Reference to expense if type is expense
@Column({
type: "text",
nullable: true,
})
description: string; // Description (e.g., "Limpesa e Seguranca", "Outros Serviso Correntes")
@Column({
nullable: true,
length: 64,
})
document_number: string; // No. Doc.
@Column({
nullable: true,
length: 64,
})
fund_code: string; // Fund code
@ManyToOne(() => FinanceAgencia, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
division_classification: FinanceAgencia; // Division Classification
@ManyToOne(() => FinanceAtividade, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
activity_classification: FinanceAtividade; // Activity Classification
@ManyToOne(() => FinanceSubBudgetLine, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
rubric_sub_rubric: FinanceSubBudgetLine; // Rubric/Sub-Rubric
@ManyToOne(() => FinanceLocalizacao, { onDelete: "NO ACTION", nullable: true })
@JoinColumn()
location_code: FinanceLocalizacao; // Location Code
@Column({
nullable: true,
type: "float8",
default: 0,
})
entry_fund: number; // Entry Fund (USD $) - for credits
@Column({
nullable: true,
type: "float8",
default: 0,
})
expenses: number; // Expenses (USD $) - for expenses
@Column({
nullable: false,
type: "float8",
})
balance: number; // Running balance after this transaction
@Column({
type: "text",
nullable: true,
})
observation: string; // Observation/Notes
@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;
}

View File

@ -12,6 +12,10 @@ export * from "../entity/finance/finance_plan_items";
export * from "../entity/finance/finance_purchase_requests"; export * from "../entity/finance/finance_purchase_requests";
export * from "../entity/finance/finance_purchase_request_items"; export * from "../entity/finance/finance_purchase_request_items";
export * from "../entity/finance/finance_cpvs"; export * from "../entity/finance/finance_cpvs";
export * from "../entity/finance/finance_checklist_payment";
export * from "../entity/finance/finance_checklist_payment_item";
export * from "../entity/finance/finance_checklist_payment_approval";
export * from "../entity/finance/finance_checklist_payment_document";
export * from "../entity/finance/finance_payment_orders"; export * from "../entity/finance/finance_payment_orders";
export * from "../entity/finance/finance_petty_cash_pockets"; export * from "../entity/finance/finance_petty_cash_pockets";
export * from "../entity/finance/finance_petty_cash_credits"; export * from "../entity/finance/finance_petty_cash_credits";

View File

@ -53,3 +53,38 @@ export enum PettyCashTransactionType {
credit = "credit", // Topup/Entry credit = "credit", // Topup/Entry
expense = "expense", // Deduct/Expense expense = "expense", // Deduct/Expense
} }
export enum FinanceChecklistPaymentItemType {
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 FinanceChecklistPaymentApprovalRole {
PREPARER = "preparer",
VERIFIER = "verifier",
APPROVER = "approver",
}
export enum FinanceChecklistPaymentStatus {
DRAFT = "draft",
PENDING_VERIFY = "pending_verifier",
PENDING_APPROVE = "pending_approver",
SUCCESS = "success",
REJECTED = "rejected",
}
export enum FinanceChecklistPaymentType {
SALARY_PAYMENT = "salary_payment",
DIRECT_PAYMENT = "direct_payment",
}