打通 T+ 快照、业务、发货、回款和核算准备链路,保留来源差异并提供待补状态。 新增业务自动接入任务、跨平台读取服务托管、权限复核、来源关联和前端核对页面。 补充迁移、隔离集成测试、浏览器模拟验收及角色授权边界修复。
34 lines
1.7 KiB
Python
34 lines
1.7 KiB
Python
"""批量补充空分类,不覆盖已有分类或冻结资料。"""
|
|
|
|
from sqlalchemy import select, update
|
|
|
|
from app.core.exceptions import BadRequestError
|
|
from app.models import BusinessItem, Customer, PayrollInput, Product
|
|
from app.services.audit_service import AuditRecord, audit
|
|
|
|
|
|
def fill_missing_product_items(session, product_ids, category):
|
|
"""补齐未封存业务的空分类,保留既有分类及历史核算依据。"""
|
|
frozen = select(PayrollInput.id).where(PayrollInput.business_id == BusinessItem.business_id).exists()
|
|
session.execute(update(BusinessItem).where(
|
|
BusinessItem.product_id.in_(product_ids), BusinessItem.product_category.is_(None), ~frozen,
|
|
).values(product_category=category))
|
|
|
|
|
|
def fill_missing(session, model, payload, actor, meta=None):
|
|
field = Customer.customer_type if model is Customer else Product.product_category
|
|
module = "客户管理" if model is Customer else "产品管理"
|
|
with audit(session, operator=actor, meta=meta, record=AuditRecord(
|
|
module=module, action="批量补充分类", summary=f"批量补充 {len(payload.ids)} 条档案分类",
|
|
request_data=payload.model_dump(mode="json"),
|
|
)):
|
|
rows = list(session.scalars(select(model).where(model.id.in_(payload.ids)).order_by(model.id).with_for_update()))
|
|
if len(rows) != len(payload.ids) or any(getattr(row, field.key) is not None for row in rows):
|
|
raise BadRequestError("所选档案不存在或分类已变化,请刷新后重新选择")
|
|
for row in rows:
|
|
setattr(row, field.key, payload.category)
|
|
if model is Product:
|
|
fill_missing_product_items(session, payload.ids, payload.category)
|
|
session.commit()
|
|
return {"updated": len(rows)}
|