-- =============================================
-- 智慧水务管理系统 - 电子发票 + 应收应付 + 催缴 DDL
-- 版本: V_invoice_account
-- =============================================

-- 电子发票表
CREATE TABLE IF NOT EXISTS rev_invoice (
    id BIGSERIAL PRIMARY KEY,
    invoice_no VARCHAR(30) UNIQUE NOT NULL,
    invoice_type VARCHAR(20) NOT NULL DEFAULT 'electronic',  -- normal/special/electronic
    customer_id BIGINT NOT NULL,
    customer_name VARCHAR(100),
    customer_tax_no VARCHAR(30),
    amount DECIMAL(12,2) NOT NULL,
    tax_rate DECIMAL(5,2) DEFAULT 6.00,
    tax_amount DECIMAL(12,2) NOT NULL,
    total_amount DECIMAL(12,2) NOT NULL,
    content VARCHAR(500),
    bill_id BIGINT,
    status VARCHAR(20) NOT NULL DEFAULT 'draft',             -- draft/issued/sent/cancelled/red
    issue_date DATE,
    push_status VARCHAR(20) DEFAULT 'none',                  -- none/email/sms/both
    push_time TIMESTAMP,
    email VARCHAR(100),
    phone VARCHAR(20),
    cancel_reason VARCHAR(500),
    original_invoice_id BIGINT,                              -- 红冲关联的原发票
    operator_id BIGINT,
    operator_name VARCHAR(50),
    remark VARCHAR(500),
    deleted SMALLINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE rev_invoice IS '电子发票表';
CREATE INDEX IF NOT EXISTS idx_invoice_customer ON rev_invoice(customer_id);
CREATE INDEX IF NOT EXISTS idx_invoice_bill ON rev_invoice(bill_id);
CREATE INDEX IF NOT EXISTS idx_invoice_status ON rev_invoice(status);
CREATE INDEX IF NOT EXISTS idx_invoice_issue_date ON rev_invoice(issue_date);

-- 应收账款表
CREATE TABLE IF NOT EXISTS rev_receivable (
    id BIGSERIAL PRIMARY KEY,
    receivable_no VARCHAR(30) UNIQUE NOT NULL,
    bill_period VARCHAR(10) NOT NULL,                        -- 2026-06
    customer_id BIGINT NOT NULL,
    customer_name VARCHAR(100),
    amount DECIMAL(12,2) NOT NULL,
    received_amount DECIMAL(12,2) DEFAULT 0,
    unreceived_amount DECIMAL(12,2) NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'pending',           -- pending/partial/completed/overdue/cancelled
    bill_id BIGINT,
    due_date DATE,
    overdue_days INT DEFAULT 0,
    collection_count INT DEFAULT 0,
    last_collection_time TIMESTAMP,
    operator_id BIGINT,
    remark VARCHAR(500),
    deleted SMALLINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE rev_receivable IS '应收账款表';
CREATE INDEX IF NOT EXISTS idx_receivable_customer ON rev_receivable(customer_id);
CREATE INDEX IF NOT EXISTS idx_receivable_period ON rev_receivable(bill_period);
CREATE INDEX IF NOT EXISTS idx_receivable_status ON rev_receivable(status);
CREATE INDEX IF NOT EXISTS idx_receivable_due_date ON rev_receivable(due_date);

-- 应付账款表
CREATE TABLE IF NOT EXISTS rev_payable (
    id BIGSERIAL PRIMARY KEY,
    payable_no VARCHAR(30) UNIQUE NOT NULL,
    bill_period VARCHAR(10) NOT NULL,                        -- 2026-06
    supplier_id BIGINT NOT NULL,
    supplier_name VARCHAR(100),
    amount DECIMAL(12,2) NOT NULL,
    paid_amount DECIMAL(12,2) DEFAULT 0,
    unpaid_amount DECIMAL(12,2) NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'pending',           -- pending/partial/completed/cancelled
    expense_type VARCHAR(30),                                -- electricity/chemical/maintenance/equipment/other
    due_date DATE,
    invoice_no VARCHAR(50),
    contract_no VARCHAR(50),
    operator_id BIGINT,
    remark VARCHAR(500),
    deleted SMALLINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE rev_payable IS '应付账款表';
CREATE INDEX IF NOT EXISTS idx_payable_supplier ON rev_payable(supplier_id);
CREATE INDEX IF NOT EXISTS idx_payable_period ON rev_payable(bill_period);
CREATE INDEX IF NOT EXISTS idx_payable_status ON rev_payable(status);
CREATE INDEX IF NOT EXISTS idx_payable_due_date ON rev_payable(due_date);

-- 对账记录表
CREATE TABLE IF NOT EXISTS rev_reconciliation (
    id BIGSERIAL PRIMARY KEY,
    reconciliation_no VARCHAR(30) UNIQUE NOT NULL,
    bill_period VARCHAR(10) NOT NULL,
    reconciliation_type VARCHAR(20) DEFAULT 'all',           -- receivable/payable/all
    total_receivable DECIMAL(14,2) DEFAULT 0,
    total_received DECIMAL(14,2) DEFAULT 0,
    total_payable DECIMAL(14,2) DEFAULT 0,
    total_paid DECIMAL(14,2) DEFAULT 0,
    difference DECIMAL(14,2) DEFAULT 0,
    status VARCHAR(20) NOT NULL DEFAULT 'draft',             -- draft/pending/approved/rejected/completed
    start_date DATE,
    end_date DATE,
    exception_count INT DEFAULT 0,
    exception_note TEXT,
    auditor_id BIGINT,
    auditor_name VARCHAR(50),
    audit_time TIMESTAMP,
    operator_id BIGINT,
    operator_name VARCHAR(50),
    remark VARCHAR(500),
    deleted SMALLINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE rev_reconciliation IS '对账记录表';
CREATE INDEX IF NOT EXISTS idx_reconciliation_period ON rev_reconciliation(bill_period);
CREATE INDEX IF NOT EXISTS idx_reconciliation_status ON rev_reconciliation(status);

-- 催缴记录表
CREATE TABLE IF NOT EXISTS rev_collection_record (
    id BIGSERIAL PRIMARY KEY,
    collection_no VARCHAR(30) UNIQUE NOT NULL,
    customer_id BIGINT NOT NULL,
    customer_name VARCHAR(100),
    overdue_amount DECIMAL(12,2) NOT NULL,
    overdue_days INT DEFAULT 0,
    collection_type VARCHAR(20) NOT NULL,                    -- sms/phone/visit/letter
    collection_result VARCHAR(20),                           -- success/promised/failed/unreachable/refused
    contact_person VARCHAR(50),
    contact_phone VARCHAR(20),
    contact_email VARCHAR(100),
    collection_time TIMESTAMP,
    promised_date DATE,
    collector_id BIGINT,
    collector_name VARCHAR(50),
    receivable_id BIGINT,
    remark VARCHAR(500),
    status VARCHAR(20) DEFAULT 'pending',                    -- pending/in_progress/completed/cancelled
    deleted SMALLINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE rev_collection_record IS '催缴记录表';
CREATE INDEX IF NOT EXISTS idx_collection_customer ON rev_collection_record(customer_id);
CREATE INDEX IF NOT EXISTS idx_collection_receivable ON rev_collection_record(receivable_id);
CREATE INDEX IF NOT EXISTS idx_collection_status ON rev_collection_record(status);
CREATE INDEX IF NOT EXISTS idx_collection_time ON rev_collection_record(collection_time);
CREATE INDEX IF NOT EXISTS idx_collection_type ON rev_collection_record(collection_type);
