实现企业银行账户与建行制单(corporate-bank-account-payment-order)
这个提交包含在:
@@ -0,0 +1,78 @@
|
||||
-- Create bank institution master data.
|
||||
CREATE TABLE "bank_institutions" (
|
||||
"id" UUID NOT NULL,
|
||||
"code" VARCHAR(16) NOT NULL,
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"archived_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"created_by" UUID,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_by" UUID,
|
||||
CONSTRAINT "bank_institutions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "bank_institutions_code_key" ON "bank_institutions"("code");
|
||||
CREATE INDEX "idx_bank_institutions_status" ON "bank_institutions"("enabled", "archived_at");
|
||||
|
||||
-- Create legal-entity-owned company payment accounts.
|
||||
CREATE TABLE "payment_accounts" (
|
||||
"id" UUID NOT NULL,
|
||||
"legal_entity_id" UUID NOT NULL,
|
||||
"bank_institution_id" UUID NOT NULL,
|
||||
"account_name" VARCHAR(120) NOT NULL,
|
||||
"account_number_encrypted" TEXT NOT NULL,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"archived_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"created_by" UUID,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_by" UUID,
|
||||
CONSTRAINT "payment_accounts_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE INDEX "idx_payment_accounts_legal_entity_status" ON "payment_accounts"("legal_entity_id", "enabled", "archived_at");
|
||||
CREATE INDEX "idx_payment_accounts_bank_institution" ON "payment_accounts"("bank_institution_id");
|
||||
CREATE UNIQUE INDEX "payment_accounts_one_active_per_legal_entity_ux"
|
||||
ON "payment_accounts"("legal_entity_id")
|
||||
WHERE "enabled" = true AND "archived_at" IS NULL;
|
||||
|
||||
ALTER TABLE "payment_accounts"
|
||||
ADD CONSTRAINT "payment_accounts_legal_entity_id_fkey"
|
||||
FOREIGN KEY ("legal_entity_id") REFERENCES "legal_entities"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "payment_accounts"
|
||||
ADD CONSTRAINT "payment_accounts_bank_institution_id_fkey"
|
||||
FOREIGN KEY ("bank_institution_id") REFERENCES "bank_institutions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- Employee bank identity is intentionally nullable; existing free text is not guessed.
|
||||
ALTER TABLE "employees" ADD COLUMN "bank_institution_id" UUID;
|
||||
CREATE INDEX "idx_employees_bank_institution" ON "employees"("bank_institution_id");
|
||||
ALTER TABLE "employees"
|
||||
ADD CONSTRAINT "employees_bank_institution_id_fkey"
|
||||
FOREIGN KEY ("bank_institution_id") REFERENCES "bank_institutions"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- Historical payment batches remain nullable and cannot be order-exported.
|
||||
ALTER TABLE "payment_batches"
|
||||
ADD COLUMN "legal_entity_id" UUID,
|
||||
ADD COLUMN "payment_account_id" UUID,
|
||||
ADD COLUMN "payment_account_snapshot_json" JSONB,
|
||||
ADD COLUMN "payment_order_export_count" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "payment_order_last_exported_at" TIMESTAMP(3),
|
||||
ADD COLUMN "payment_order_last_exported_by" UUID;
|
||||
|
||||
CREATE INDEX "idx_payment_batches_legal_entity" ON "payment_batches"("legal_entity_id");
|
||||
CREATE INDEX "idx_payment_batches_payment_account" ON "payment_batches"("payment_account_id");
|
||||
CREATE INDEX "idx_payment_batches_order_exported_by" ON "payment_batches"("payment_order_last_exported_by");
|
||||
|
||||
ALTER TABLE "payment_batches"
|
||||
ADD CONSTRAINT "payment_batches_legal_entity_id_fkey"
|
||||
FOREIGN KEY ("legal_entity_id") REFERENCES "legal_entities"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "payment_batches"
|
||||
ADD CONSTRAINT "payment_batches_payment_account_id_fkey"
|
||||
FOREIGN KEY ("payment_account_id") REFERENCES "payment_accounts"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "payment_batches"
|
||||
ADD CONSTRAINT "payment_batches_payment_order_last_exported_by_fkey"
|
||||
FOREIGN KEY ("payment_order_last_exported_by") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -598,6 +598,7 @@ model Employee {
|
||||
|
||||
bank_account_encrypted String
|
||||
bank_name String
|
||||
bank_institution_id String? @db.Uuid
|
||||
id_number_encrypted String?
|
||||
|
||||
password_hash String
|
||||
@@ -625,6 +626,7 @@ model Employee {
|
||||
|
||||
department Department @relation(fields: [department_id], references: [id], onDelete: Restrict)
|
||||
legal_entity LegalEntity? @relation(fields: [legal_entity_id], references: [id], onDelete: SetNull)
|
||||
bank_institution BankInstitution? @relation(fields: [bank_institution_id], references: [id], onDelete: SetNull)
|
||||
direct_manager Employee? @relation("EmployeeToManager", fields: [direct_manager_id], references: [id], onDelete: Restrict)
|
||||
subordinates Employee[] @relation("EmployeeToManager")
|
||||
|
||||
@@ -642,6 +644,7 @@ model Employee {
|
||||
paid_reimbursements ReimbursementForm[] @relation("ReimbursementPaidBy")
|
||||
reimbursement_attachments_uploaded ReimbursementAttachment[] @relation("ReimbursementAttachmentUploader")
|
||||
payment_batch_receipts_uploaded PaymentBatchReceiptAttachment[] @relation("PaymentBatchReceiptAttachmentUploader")
|
||||
payment_batches_last_exported PaymentBatch[] @relation("PaymentOrderLastExportedBy")
|
||||
leave_requests LeaveRequest[]
|
||||
leave_ledgers LeaveLedger[]
|
||||
wecom_checkin_records WecomCheckinRecord[]
|
||||
@@ -724,6 +727,7 @@ model Employee {
|
||||
|
||||
@@index([department_id])
|
||||
@@index([legal_entity_id], map: "idx_employees_legal_entity")
|
||||
@@index([bank_institution_id], map: "idx_employees_bank_institution")
|
||||
@@index([direct_manager_id])
|
||||
@@map("employees")
|
||||
}
|
||||
@@ -985,12 +989,56 @@ model LegalEntity {
|
||||
card_authorizations CardAuthorization[]
|
||||
asset_cards AssetCard[]
|
||||
budget_pools BudgetPool[] @relation("BudgetPoolLegalEntity")
|
||||
payment_accounts PaymentAccount[]
|
||||
payment_batches PaymentBatch[]
|
||||
|
||||
@@index([enabled, archived_at], map: "idx_legal_entities_status")
|
||||
@@index([default_holiday_calendar_id], map: "idx_legal_entities_default_calendar")
|
||||
@@map("legal_entities")
|
||||
}
|
||||
|
||||
model BankInstitution {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
code String @unique @db.VarChar(16)
|
||||
name String @db.VarChar(100)
|
||||
enabled Boolean @default(true)
|
||||
archived_at DateTime?
|
||||
|
||||
created_at DateTime @default(now())
|
||||
created_by String? @db.Uuid
|
||||
updated_at DateTime @default(now()) @updatedAt
|
||||
updated_by String? @db.Uuid
|
||||
|
||||
employees Employee[]
|
||||
payment_accounts PaymentAccount[]
|
||||
|
||||
@@index([enabled, archived_at], map: "idx_bank_institutions_status")
|
||||
@@map("bank_institutions")
|
||||
}
|
||||
|
||||
model PaymentAccount {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
legal_entity_id String @db.Uuid
|
||||
bank_institution_id String @db.Uuid
|
||||
account_name String @db.VarChar(120)
|
||||
account_number_encrypted String
|
||||
enabled Boolean @default(true)
|
||||
archived_at DateTime?
|
||||
|
||||
created_at DateTime @default(now())
|
||||
created_by String? @db.Uuid
|
||||
updated_at DateTime @default(now()) @updatedAt
|
||||
updated_by String? @db.Uuid
|
||||
|
||||
legal_entity LegalEntity @relation(fields: [legal_entity_id], references: [id], onDelete: Restrict)
|
||||
bank_institution BankInstitution @relation(fields: [bank_institution_id], references: [id], onDelete: Restrict)
|
||||
payment_batches PaymentBatch[]
|
||||
|
||||
@@index([legal_entity_id, enabled, archived_at], map: "idx_payment_accounts_legal_entity_status")
|
||||
@@index([bank_institution_id], map: "idx_payment_accounts_bank_institution")
|
||||
@@map("payment_accounts")
|
||||
}
|
||||
|
||||
model CostCenter {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
legal_entity_id String @db.Uuid
|
||||
@@ -1856,6 +1904,12 @@ model PaymentBatch {
|
||||
review_comment String?
|
||||
secondary_review_comment String?
|
||||
execution_summary_json Json?
|
||||
legal_entity_id String? @db.Uuid
|
||||
payment_account_id String? @db.Uuid
|
||||
payment_account_snapshot_json Json?
|
||||
payment_order_export_count Int @default(0)
|
||||
payment_order_last_exported_at DateTime?
|
||||
payment_order_last_exported_by String? @db.Uuid
|
||||
|
||||
created_at DateTime @default(now())
|
||||
created_by String? @db.Uuid
|
||||
@@ -1873,8 +1927,14 @@ model PaymentBatch {
|
||||
|
||||
items PaymentBatchItem[]
|
||||
receipt_attachments PaymentBatchReceiptAttachment[]
|
||||
legal_entity LegalEntity? @relation(fields: [legal_entity_id], references: [id], onDelete: SetNull)
|
||||
payment_account PaymentAccount? @relation(fields: [payment_account_id], references: [id], onDelete: SetNull)
|
||||
payment_order_last_exported_by_employee Employee? @relation("PaymentOrderLastExportedBy", fields: [payment_order_last_exported_by], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([entity_type, status, created_at], map: "idx_payment_batches_entity_status_created")
|
||||
@@index([legal_entity_id], map: "idx_payment_batches_legal_entity")
|
||||
@@index([payment_account_id], map: "idx_payment_batches_payment_account")
|
||||
@@index([payment_order_last_exported_by], map: "idx_payment_batches_order_exported_by")
|
||||
@@map("payment_batches")
|
||||
}
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户