"""批量补充空分类,不覆盖已有分类或冻结资料。""" 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)}