Przeglądaj źródła

fix: 手工发放跳过校验失败的员工,不更新本地记录

alphah 2 tygodni temu
rodzic
commit
d891443020

+ 108 - 18
backend/app/plugin/module_payment/expense/quota/service.py

@@ -419,38 +419,128 @@ class QuotaService:
         except Exception as e:
             log.warning(f"保存发放批次记录失败(不影响发放): {e}")
 
-        # 保存每条额度到 pay_expense_quota(确保额度管理页面有数据)
+        # 组装校验失败列表(在更新本地记录前获取,用于过滤)
+        failed_owner_ids: set[str] = set()
+        if hasattr(result, 'issue_quota_check_failed_list') and result.issue_quota_check_failed_list:
+            failed_owner_ids = {
+                str(getattr(f, 'owner_id', ''))
+                for f in result.issue_quota_check_failed_list
+                if getattr(f, 'owner_id', None)
+            }
+
+        # 更新本地额度记录(跳过校验失败的员工)
         try:
             from app.plugin.module_payment.expense.quota.model import QuotaModel
             from app.plugin.module_payment.expense.quota.enums import QuotaStatusEnum
-            from sqlalchemy import insert
+            from sqlalchemy import insert, select, update as sa_update
             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_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
             if data.issue_target_info_list:
                 for item in data.issue_target_info_list:
+                    emp_id = (item.owner_id or "")
+                    # 跳过支付宝校验失败的员工
+                    if emp_id in failed_owner_ids:
+                        log.warning(f"手工发放 - 跳过校验失败员工: owner_id={emp_id}")
+                        continue
                     try:
                         quota_amount = Decimal(item.issue_quota)
                     except Exception:
                         quota_amount = Decimal("0")
-                    stmt = insert(QuotaModel).values(
-                        employee_id=item.owner_id or "",
-                        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}_{item.owner_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,
+
+                    # 查询是否已有该员工在该制度下的额度记录
+                    check = select(QuotaModel).where(
+                        QuotaModel.employee_id == emp_id,
+                        QuotaModel.institution_id == data.institution_id,
                     )
-                    await auth.db.execute(stmt)
+                    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.flush()
-                log.info(f"手工发放 - 保存 {len(data.issue_target_info_list)} 条额度记录到本地")
+                log.info(f"手工发放 - 更新 {updated_count} 条、新增 {inserted_count} 条额度记录到本地(跳过 {len(failed_owner_ids)} 条校验失败)")
+
+            # 查询支付宝端的发放记录,获取每个员工的 real quota_id 并更新本地记录
+            try:
+                from alipay.aop.api.request.AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryRequest import (
+                    AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryRequest,
+                )
+                from alipay.aop.api.domain.AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryModel import (
+                    AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryModel,
+                )
+                from alipay.aop.api.response.AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryResponse import (
+                    AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryResponse,
+                )
+                records_model = AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryModel()
+                records_model.enterprise_id = data.enterprise_id
+                records_model.institution_id = data.institution_id
+                records_model.issue_batch_id = result.issue_batch_id
+                records_model.page_size = len(data.issue_target_info_list)
+                records_model.page_num = 1
+
+                records_request = AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryRequest()
+                records_request.biz_model = records_model
+
+                records_response = client.execute(records_request)
+
+                if records_response:
+                    records_result = AlipayEbppInvoiceIssuebatchIssuerecordsBatchqueryResponse()
+                    records_result.parse_response_content(records_response)
+                    if records_result.is_success() and hasattr(records_result, 'issue_record_info_list') and records_result.issue_record_info_list:
+                        updated_quota_id_count = 0
+                        for r in records_result.issue_record_info_list:
+                            quota_id = getattr(r, 'quota_id', None)
+                            owner_id = getattr(r, 'owner_id', None)
+                            if quota_id and owner_id:
+                                upd_q = sa_update(QuotaModel).where(
+                                    QuotaModel.employee_id == owner_id,
+                                    QuotaModel.institution_id == data.institution_id,
+                                ).values(quota_id=quota_id)
+                                await auth.db.execute(upd_q)
+                                updated_quota_id_count += 1
+                        if updated_quota_id_count:
+                            await auth.db.flush()
+                            log.info(f"手工发放 - 已从支付宝查询并更新 {updated_quota_id_count} 条记录的 quota_id")
+            except Exception as e:
+                log.warning(f"查询支付宝发放记录获取 quota_id 失败(不影响发放): {e}")
+
         except Exception as e:
             log.warning(f"保存额度记录到本地失败(不影响发放): {e}")