Преглед изворни кода

fix: 同一员工多次发放各自独立记录,作废只删本批次记录

alphah пре 2 недеља
родитељ
комит
072b01fb6b
1 измењених фајлова са 47 додато и 87 уклоњено
  1. 47 87
      backend/app/plugin/module_payment/expense/quota/service.py

+ 47 - 87
backend/app/plugin/module_payment/expense/quota/service.py

@@ -441,16 +441,15 @@ class QuotaService:
                 if getattr(f, 'owner_id', None)
                 if getattr(f, 'owner_id', None)
             }
             }
 
 
-        # 更新本地额度记录(跳过校验失败的员工
+        # 为每个员工插入新的额度记录(每次发放独立记录,支持同一员工多次发放
         try:
         try:
             from app.plugin.module_payment.expense.quota.model import QuotaModel
             from app.plugin.module_payment.expense.quota.model import QuotaModel
             from app.plugin.module_payment.expense.quota.enums import QuotaStatusEnum
             from app.plugin.module_payment.expense.quota.enums import QuotaStatusEnum
-            from sqlalchemy import insert, select, update as sa_update
+            from sqlalchemy import insert
             tenant_id = auth.user.tenant_id if auth.user else 1
             tenant_id = auth.user.tenant_id if auth.user else 1
             effective_start = datetime.strptime(data.effective_start_date, "%Y-%m-%d %H:%M:%S") if data.effective_start_date else None
             effective_start = datetime.strptime(data.effective_start_date, "%Y-%m-%d %H:%M:%S") if data.effective_start_date else None
             effective_end = datetime.strptime(data.effective_end_date, "%Y-%m-%d %H:%M:%S") if data.effective_end_date else None
             effective_end = datetime.strptime(data.effective_end_date, "%Y-%m-%d %H:%M:%S") if data.effective_end_date else None
 
 
-            updated_count = 0
             inserted_count = 0
             inserted_count = 0
             if data.issue_target_info_list:
             if data.issue_target_info_list:
                 for item in data.issue_target_info_list:
                 for item in data.issue_target_info_list:
@@ -464,51 +463,26 @@ class QuotaService:
                     except Exception:
                     except Exception:
                         quota_amount = Decimal("0")
                         quota_amount = Decimal("0")
 
 
-                    # 查询是否已有该员工在该制度下的额度记录
-                    check = select(QuotaModel).where(
-                        QuotaModel.employee_id == emp_id,
-                        QuotaModel.institution_id == data.institution_id,
+                    # 每次都新增独立记录,不覆盖已有记录
+                    stmt = insert(QuotaModel).values(
+                        employee_id=emp_id,
+                        institution_id=data.institution_id,
+                        quota_type=data.quota_type,
+                        target_type="INSTITUTION",
+                        target_id=data.institution_id,
+                        out_biz_no=f"batch_{data.batch_no}_{emp_id}",
+                        total_amount=quota_amount,
+                        available_amount=quota_amount,
+                        status=QuotaStatusEnum.QUOTA_ACTIVE.value,
+                        valid_from=effective_start,
+                        valid_to=effective_end,
+                        enterprise_id=data.enterprise_id,
+                        tenant_id=tenant_id,
                     )
                     )
-                    existing = await auth.db.execute(check)
-                    existing_quota = existing.scalar_one_or_none()
-
-                    if existing_quota:
-                        # 已有记录 → 更新金额、状态、有效期
-                        upd = sa_update(QuotaModel).where(
-                            QuotaModel.id == existing_quota.id
-                        ).values(
-                            total_amount=quota_amount,
-                            available_amount=quota_amount,
-                            status=QuotaStatusEnum.QUOTA_ACTIVE.value,
-                            quota_type=data.quota_type,
-                            valid_from=effective_start,
-                            valid_to=effective_end,
-                            target_type="INSTITUTION",
-                            target_id=data.institution_id,
-                        )
-                        await auth.db.execute(upd)
-                        updated_count += 1
-                    else:
-                        # 没有记录 → 新增
-                        stmt = insert(QuotaModel).values(
-                            employee_id=emp_id,
-                            institution_id=data.institution_id,
-                            quota_type=data.quota_type,
-                            target_type="INSTITUTION",
-                            target_id=data.institution_id,
-                            out_biz_no=f"batch_{data.batch_no}_{emp_id}",
-                            total_amount=quota_amount,
-                            available_amount=quota_amount,
-                            status=QuotaStatusEnum.QUOTA_ACTIVE.value,
-                            valid_from=effective_start,
-                            valid_to=effective_end,
-                            enterprise_id=data.enterprise_id,
-                            tenant_id=tenant_id,
-                        )
-                        await auth.db.execute(stmt)
-                        inserted_count += 1
+                    await auth.db.execute(stmt)
+                    inserted_count += 1
                 await auth.db.flush()
                 await auth.db.flush()
-                log.info(f"手工发放 - 更新 {updated_count} 条、新增 {inserted_count} 条额度记录到本地(跳过 {len(failed_owner_ids)} 条校验失败)")
+                log.info(f"手工发放 - 新增 {inserted_count} 条额度记录(跳过 {len(failed_owner_ids)} 条校验失败)")
 
 
             # 查询支付宝端的发放记录,获取每个员工的 real quota_id 并更新本地记录
             # 查询支付宝端的发放记录,获取每个员工的 real quota_id 并更新本地记录
             try:
             try:
@@ -542,11 +516,12 @@ class QuotaService:
                             quota_id = getattr(r, 'quota_id', None)
                             quota_id = getattr(r, 'quota_id', None)
                             owner_id = getattr(r, 'owner_id', None)
                             owner_id = getattr(r, 'owner_id', None)
                             if quota_id and owner_id:
                             if quota_id and owner_id:
-                                upd_q = sa_update(QuotaModel).where(
-                                    QuotaModel.employee_id == owner_id,
+                                # 按 out_biz_no 模式匹配,只更新本批次插入的记录
+                                q_upd = sa_update(QuotaModel).where(
+                                    QuotaModel.out_biz_no == f"batch_{data.batch_no}_{owner_id}",
                                     QuotaModel.institution_id == data.institution_id,
                                     QuotaModel.institution_id == data.institution_id,
                                 ).values(quota_id=quota_id)
                                 ).values(quota_id=quota_id)
-                                await auth.db.execute(upd_q)
+                                await auth.db.execute(q_upd)
                                 updated_quota_id_count += 1
                                 updated_quota_id_count += 1
                         if updated_quota_id_count:
                         if updated_quota_id_count:
                             await auth.db.flush()
                             await auth.db.flush()
@@ -631,47 +606,32 @@ class QuotaService:
         except Exception as e:
         except Exception as e:
             log.warning(f"更新批次本地状态失败(不影响作废): {e}")
             log.warning(f"更新批次本地状态失败(不影响作废): {e}")
 
 
-        # 作废批次后,将涉及员工的额度记录回退为待发放状态
+        # 作废批次后,删除该批次创建的额度记录
         try:
         try:
             from app.plugin.module_payment.expense.quota.model import QuotaModel
             from app.plugin.module_payment.expense.quota.model import QuotaModel
-            from app.plugin.module_payment.expense.quota.enums import QuotaStatusEnum
-            from sqlalchemy import select, update as sa_update
-
-            records_resp = await cls.issue_batch_records_query_service(
-                auth,
-                IssueBatchRecordsQuerySchema(
-                    enterprise_id=data.enterprise_id,
-                    institution_id=data.institution_id,
-                    issue_batch_id=data.issue_batch_id,
-                    page_size=100,
-                    page_num=1,
-                ),
-            )
-            if records_resp.issue_record_info_list:
-                reset_count = 0
-                for record in records_resp.issue_record_info_list:
-                    if record.issue_status != 1:
-                        continue
-                    owner_id = record.owner_id
-                    quota_id = record.quota_id
-                    if not owner_id:
-                        continue
-                    upd = sa_update(QuotaModel).where(
-                        QuotaModel.employee_id == owner_id,
-                        QuotaModel.institution_id == data.institution_id,
-                    ).values(
-                        total_amount=0,
-                        available_amount=0,
-                        status=QuotaStatusEnum.QUOTA_PENDING.value,
-                        quota_id=None,
-                    )
-                    await auth.db.execute(upd)
-                    reset_count += 1
-                if reset_count:
-                    await auth.db.flush()
-                    log.info(f"批次作废 - 已回退 {reset_count} 条额度记录为待发放状态")
+            from sqlalchemy import delete as sa_delete
+
+            # 从本地批次记录获取 batch_no
+            issue_batch_crud = IssueBatchCRUD(auth)
+            batch = await issue_batch_crud.get_by_issue_batch_id(data.issue_batch_id)
+            batch_no = batch.batch_no if batch else None
+
+            if batch_no:
+                # 按 out_biz_no 模式匹配: batch_{batch_no}_%
+                pattern = f"batch_{batch_no}_%"
+                del_stmt = sa_delete(QuotaModel).where(
+                    QuotaModel.out_biz_no.like(pattern),
+                    QuotaModel.institution_id == data.institution_id,
+                )
+                await auth.db.execute(del_stmt)
+                await auth.db.flush()
+                log.info(f"批次作废 - 已删除该批次创建的额度记录: batch_no={batch_no}")
         except Exception as e:
         except Exception as e:
-            log.warning(f"回退额度记录失败(不影响作废): {e}")
+            log.warning(f"删除额度记录失败(不影响作废): {e}")
+
+        return IssueBatchCancelOutSchema(
+            result=getattr(result, 'result', False),
+        )
 
 
         return IssueBatchCancelOutSchema(
         return IssueBatchCancelOutSchema(
             result=getattr(result, 'result', False),
             result=getattr(result, 'result', False),