dy-dashboard/services/contract_ledger.py
2026-10-28 11:14:17 +08:00

145 lines
6.0 KiB
Python

"""Database model helpers for generated-contract ledger records."""
import json
import uuid
from datetime import datetime
from services.db import query
_schema_ready = False
_TYPE_CODES = {'domestic': 'GN', 'overseas': 'HW', 'packaging': 'BC'}
def ensure_schema():
global _schema_ready
if _schema_ready:
return
query("""
CREATE TABLE IF NOT EXISTS contract_records (
id BIGINT NOT NULL AUTO_INCREMENT,
contract_no VARCHAR(80) NOT NULL,
supplier_id INT NULL,
supplier_name VARCHAR(255) NOT NULL DEFAULT '',
buyer_name VARCHAR(255) NOT NULL DEFAULT '',
order_type VARCHAR(32) NOT NULL DEFAULT '',
template_id INT NULL,
template_name VARCHAR(100) NOT NULL DEFAULT '',
order_count INT NOT NULL DEFAULT 0,
product_count INT NOT NULL DEFAULT 0,
total_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
status VARCHAR(32) NOT NULL DEFAULT '已生成',
signer VARCHAR(100) NOT NULL DEFAULT '',
signed_at DATE NULL,
effective_date DATE NULL,
expiry_date DATE NULL,
payment_terms TEXT NULL,
delivery_terms TEXT NULL,
remark TEXT NULL,
order_ids_json LONGTEXT NULL,
orders_json LONGTEXT NULL,
current_file_path VARCHAR(500) NOT NULL DEFAULT '',
current_file_name VARCHAR(255) NOT NULL DEFAULT '',
created_by INT NULL,
created_by_name VARCHAR(100) NOT NULL DEFAULT '',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_by INT NULL,
updated_by_name VARCHAR(100) NOT NULL DEFAULT '',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
is_deleted TINYINT NOT NULL DEFAULT 0,
PRIMARY KEY (id),
UNIQUE KEY uk_contract_no (contract_no),
KEY idx_contract_supplier (supplier_name),
KEY idx_contract_status (status, created_at),
KEY idx_contract_type (order_type, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
""")
query("""
CREATE TABLE IF NOT EXISTS contract_files (
id BIGINT NOT NULL AUTO_INCREMENT,
contract_id BIGINT NOT NULL,
version INT NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_name VARCHAR(255) NOT NULL DEFAULT '',
generated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
generated_by INT NULL,
generated_by_name VARCHAR(100) NOT NULL DEFAULT '',
is_current TINYINT NOT NULL DEFAULT 0,
remark VARCHAR(500) NOT NULL DEFAULT '',
PRIMARY KEY (id),
UNIQUE KEY uk_contract_file_version (contract_id, version),
KEY idx_contract_file_current (contract_id, is_current)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
""")
query("""
CREATE TABLE IF NOT EXISTS contract_events (
id BIGINT NOT NULL AUTO_INCREMENT,
contract_id BIGINT NOT NULL,
action VARCHAR(80) NOT NULL,
detail TEXT NULL,
user_id INT NULL,
user_name VARCHAR(100) NOT NULL DEFAULT '',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_contract_event (contract_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
""")
_schema_ready = True
def new_contract_no(order_type, contract_short_name=None):
code = str(contract_short_name or '').strip().upper()
if not code:
code = _TYPE_CODES.get(order_type, 'QT')
return f"CGHTDY-{code}-{datetime.now():%Y%m%d}-{uuid.uuid4().hex[:6].upper()}"
def create_record(**values):
ensure_schema()
return query(
"""INSERT INTO contract_records
(contract_no, supplier_id, supplier_name, buyer_name, order_type, template_id, template_name,
order_count, product_count, total_amount, status, order_ids_json, orders_json,
current_file_path, current_file_name, created_by, created_by_name, updated_by, updated_by_name)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
(
values['contract_no'], values.get('supplier_id'), values.get('supplier_name', ''),
values.get('buyer_name', '深圳市蝶雅云联信息技术有限公司'), values.get('order_type', ''),
values.get('template_id'), values.get('template_name', ''), values.get('order_count', 0),
values.get('product_count', 0), values.get('total_amount', 0), values.get('status', '已生成'),
json.dumps(values.get('order_ids', []), ensure_ascii=False),
json.dumps(values.get('orders', []), ensure_ascii=False, default=str),
values.get('current_file_path', ''), values.get('current_file_name', ''),
values.get('created_by'), values.get('created_by_name', ''),
values.get('created_by'), values.get('created_by_name', ''),
),
)
def add_file(contract_id, version, file_path, file_name, user_id=None, user_name='', remark=''):
ensure_schema()
query("UPDATE contract_files SET is_current=0 WHERE contract_id=%s", (contract_id,))
return query(
"""INSERT INTO contract_files
(contract_id, version, file_path, file_name, generated_by, generated_by_name, is_current, remark)
VALUES (%s,%s,%s,%s,%s,%s,1,%s)""",
(contract_id, version, file_path, file_name, user_id, user_name, remark),
)
def add_event(contract_id, action, detail='', user_id=None, user_name=''):
ensure_schema()
return query(
"INSERT INTO contract_events (contract_id, action, detail, user_id, user_name) "
"VALUES (%s,%s,%s,%s,%s)",
(contract_id, action, detail, user_id, user_name),
)
def parse_json(value, default):
if not value:
return default
try:
return json.loads(value) if isinstance(value, str) else value
except (TypeError, ValueError):
return default