feat(P20T3-1,P20T3-2,P20T3-3): 对账批次引擎与ERP摘要出站后端
这个提交包含在:
+116
@@ -0,0 +1,116 @@
|
||||
ALTER TYPE "DocumentCategoryEntityType" ADD VALUE IF NOT EXISTS 'travel_reconciliation_batch';
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "TravelReconciliationBatchStatus" AS ENUM ('draft', 'reconciled');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "TravelReconciliationItemKind" AS ENUM ('order', 'orphan_transaction');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "TravelReconciliationMatchStatus" AS ENUM (
|
||||
'matched',
|
||||
'amount_mismatch',
|
||||
'currency_mismatch',
|
||||
'missing_transaction',
|
||||
'duplicate_charge',
|
||||
'orphan_transaction',
|
||||
'reversed_after_payment'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "TravelReconciliationResolutionStatus" AS ENUM ('pending', 'confirmed');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "travel_reconciliation_batches" (
|
||||
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
"batch_no" TEXT NOT NULL,
|
||||
"legal_entity_id" UUID NOT NULL,
|
||||
"cost_center_id" UUID,
|
||||
"period_start" DATE NOT NULL,
|
||||
"period_end" DATE NOT NULL,
|
||||
"status" "TravelReconciliationBatchStatus" NOT NULL DEFAULT 'draft',
|
||||
"summary_json" JSONB NOT NULL,
|
||||
"confirmed_at" TIMESTAMP(3),
|
||||
"confirmed_by" UUID,
|
||||
"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 "travel_reconciliation_batches_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "travel_reconciliation_batches_batch_no_key" ON "travel_reconciliation_batches"("batch_no");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_batches_status_period" ON "travel_reconciliation_batches"("status", "period_start", "period_end");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_batches_legal_cost_center" ON "travel_reconciliation_batches"("legal_entity_id", "cost_center_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_batches_confirmed_by" ON "travel_reconciliation_batches"("confirmed_by");
|
||||
|
||||
ALTER TABLE "travel_reconciliation_batches"
|
||||
ADD CONSTRAINT "travel_reconciliation_batches_legal_entity_id_fkey"
|
||||
FOREIGN KEY ("legal_entity_id") REFERENCES "legal_entities"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "travel_reconciliation_batches"
|
||||
ADD CONSTRAINT "travel_reconciliation_batches_cost_center_id_fkey"
|
||||
FOREIGN KEY ("cost_center_id") REFERENCES "cost_centers"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "travel_reconciliation_batches"
|
||||
ADD CONSTRAINT "travel_reconciliation_batches_confirmed_by_fkey"
|
||||
FOREIGN KEY ("confirmed_by") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "travel_reconciliation_items" (
|
||||
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
"travel_reconciliation_batch_id" UUID NOT NULL,
|
||||
"item_kind" "TravelReconciliationItemKind" NOT NULL,
|
||||
"travel_request_id" UUID,
|
||||
"travel_order_id" UUID,
|
||||
"card_transaction_id" UUID,
|
||||
"match_status" "TravelReconciliationMatchStatus" NOT NULL,
|
||||
"resolution_status" "TravelReconciliationResolutionStatus" NOT NULL DEFAULT 'pending',
|
||||
"order_amount" DECIMAL(14,2),
|
||||
"transaction_amount" DECIMAL(14,2),
|
||||
"currency" VARCHAR(8) NOT NULL DEFAULT 'CNY',
|
||||
"anomaly_code" VARCHAR(32),
|
||||
"snapshot_json" JSONB NOT NULL,
|
||||
"confirmed_at" TIMESTAMP(3),
|
||||
"confirmed_by" UUID,
|
||||
"confirm_note" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "travel_reconciliation_items_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_items_batch_resolution" ON "travel_reconciliation_items"("travel_reconciliation_batch_id", "resolution_status");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_items_request" ON "travel_reconciliation_items"("travel_request_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_items_order" ON "travel_reconciliation_items"("travel_order_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_items_transaction" ON "travel_reconciliation_items"("card_transaction_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_travel_reconciliation_items_confirmed_by" ON "travel_reconciliation_items"("confirmed_by");
|
||||
|
||||
ALTER TABLE "travel_reconciliation_items"
|
||||
ADD CONSTRAINT "travel_reconciliation_items_batch_id_fkey"
|
||||
FOREIGN KEY ("travel_reconciliation_batch_id") REFERENCES "travel_reconciliation_batches"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "travel_reconciliation_items"
|
||||
ADD CONSTRAINT "travel_reconciliation_items_travel_request_id_fkey"
|
||||
FOREIGN KEY ("travel_request_id") REFERENCES "travel_requests"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "travel_reconciliation_items"
|
||||
ADD CONSTRAINT "travel_reconciliation_items_travel_order_id_fkey"
|
||||
FOREIGN KEY ("travel_order_id") REFERENCES "travel_orders"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "travel_reconciliation_items"
|
||||
ADD CONSTRAINT "travel_reconciliation_items_card_transaction_id_fkey"
|
||||
FOREIGN KEY ("card_transaction_id") REFERENCES "card_transactions"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "travel_reconciliation_items"
|
||||
ADD CONSTRAINT "travel_reconciliation_items_confirmed_by_fkey"
|
||||
FOREIGN KEY ("confirmed_by") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
在新工单中引用
屏蔽一个用户