打通 T+ 快照、业务、发货、回款和核算准备链路,保留来源差异并提供待补状态。 新增业务自动接入任务、跨平台读取服务托管、权限复核、来源关联和前端核对页面。 补充迁移、隔离集成测试、浏览器模拟验收及角色授权边界修复。
57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
"""回款人工确认门槛;与生成凭证、保存资料和工资审核分别管理。"""
|
|
|
|
import hashlib
|
|
import json
|
|
from datetime import date
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import select
|
|
|
|
from app.core.exceptions import BadRequestError
|
|
from app.models import Receipt
|
|
from app.services.param_service import resolve_snapshot
|
|
|
|
CONFIRMATION_PARAM = "receipt.confirmation.enabled"
|
|
|
|
|
|
def enabled(session) -> bool:
|
|
"""操作开关取当前生效值,不按历史到账日绕过本次人工确认门槛。"""
|
|
return resolve_snapshot(session, date.today()).boolean(CONFIRMATION_PARAM)
|
|
|
|
|
|
def revision(receipt) -> str:
|
|
"""只绑定经办人核对的业务内容;备注和同步时间不使确认无故失效。"""
|
|
values = [
|
|
receipt.id, receipt.business_id, receipt.shipment_id,
|
|
receipt.receipt_date.isoformat(), format(Decimal(receipt.amount).quantize(Decimal("0.01")), "f"),
|
|
receipt.is_barter, receipt.t_plus_id, receipt.source_no,
|
|
]
|
|
return hashlib.sha256(json.dumps(values, ensure_ascii=False).encode()).hexdigest()
|
|
|
|
|
|
def is_confirmed(receipt) -> bool:
|
|
return bool(
|
|
receipt.confirmation_status == 1
|
|
and receipt.confirmed_by
|
|
and receipt.confirmed_at
|
|
and receipt.confirmed_revision == revision(receipt)
|
|
)
|
|
|
|
|
|
def invalidate(receipt) -> None:
|
|
receipt.confirmation_status = 0
|
|
receipt.confirmed_by = receipt.confirmed_at = receipt.confirmed_revision = None
|
|
|
|
|
|
def ensure_confirmed(session, receipt_ids) -> None:
|
|
"""在原核算事务内锁定并核实回款;关闭只跳过人工门槛,不改变凭证资格。"""
|
|
ids = sorted(set(receipt_ids))
|
|
if not ids or not enabled(session):
|
|
return
|
|
rows = list(session.scalars(
|
|
select(Receipt).where(Receipt.id.in_(ids)).order_by(Receipt.id)
|
|
.with_for_update().execution_options(populate_existing=True)
|
|
))
|
|
if len(rows) != len(ids) or any(not is_confirmed(row) for row in rows):
|
|
raise BadRequestError("存在未人工确认或确认后内容已变化的回款,请先在回款管理逐笔确认")
|