|
|
@@ -103,6 +103,7 @@ class InstitutionService:
|
|
|
enterprise_id: str,
|
|
|
scope_data: dict | None = None,
|
|
|
issuerule_data: dict | None = None,
|
|
|
+ raw_data: dict | None = None,
|
|
|
) -> dict:
|
|
|
"""
|
|
|
创建费控制度(完整串联流程)
|
|
|
@@ -111,7 +112,7 @@ class InstitutionService:
|
|
|
1. institution.create → 获取 institution_id
|
|
|
2. scope.modify ← 如有适用成员数据(scope_data)
|
|
|
3. issuerule.create ← 如为"按固定周期发放"(issuerule_data)
|
|
|
- 4. 保存到本地DB
|
|
|
+ 4. 保存到本地DB(制度 + 使用规则 + 发放规则)
|
|
|
"""
|
|
|
# 第1步:创建制度
|
|
|
institution_result = await cls.create_institution_service(auth=auth, data=institution_model)
|
|
|
@@ -194,10 +195,57 @@ class InstitutionService:
|
|
|
)
|
|
|
|
|
|
create_data_dict = create_data.model_dump(exclude_unset=True)
|
|
|
- # issue_rule_id 暂不写入模型(模型无该字段),后续扩展
|
|
|
crud = InstitutionCRUD(auth)
|
|
|
await crud.create(create_data_dict)
|
|
|
|
|
|
+ # 第5步:保存使用规则到本地
|
|
|
+ if raw_data and raw_data.get("standard_info_list") and hasattr(institution_result, 'standard_id_info_list') and institution_result.standard_id_info_list:
|
|
|
+ from app.plugin.module_payment.expense.rule.crud import RuleCRUD
|
|
|
+ from app.plugin.module_payment.expense.rule.service import RuleService
|
|
|
+ standard_id_map = {}
|
|
|
+ for info in institution_result.standard_id_info_list:
|
|
|
+ if hasattr(info, 'outer_source_id') and hasattr(info, 'standard_id'):
|
|
|
+ standard_id_map[info.outer_source_id] = info.standard_id
|
|
|
+ for idx, std in enumerate(raw_data["standard_info_list"]):
|
|
|
+ std_data = {
|
|
|
+ "out_biz_no": std.get("outer_source_id", f"std_{institution_id}_{idx}"),
|
|
|
+ "institution_id": institution_id,
|
|
|
+ "rule_id": standard_id_map.get(std.get("outer_source_id", "")),
|
|
|
+ "standard_name": std.get("standard_name"),
|
|
|
+ "standard_desc": std.get("standard_desc"),
|
|
|
+ "expense_type_sub_category": std.get("expense_type_sub_category", "DEFAULT"),
|
|
|
+ "enterprise_id": enterprise_id,
|
|
|
+ }
|
|
|
+ try:
|
|
|
+ from app.plugin.module_payment.expense.rule.model import ExpenseRuleModel
|
|
|
+ from sqlalchemy import insert
|
|
|
+ stmt = insert(ExpenseRuleModel).values(**std_data)
|
|
|
+ await auth.db.execute(stmt)
|
|
|
+ await auth.db.flush()
|
|
|
+ except Exception as e:
|
|
|
+ log.warning(f"保存使用规则到本地失败: {e}")
|
|
|
+
|
|
|
+ # 第6步:保存发放规则到本地
|
|
|
+ if issuerule_data and issue_rule_id:
|
|
|
+ from app.plugin.module_payment.expense.quota.model import QuotaModel
|
|
|
+ quota_save_data = {
|
|
|
+ "employee_id": "",
|
|
|
+ "institution_id": institution_id,
|
|
|
+ "out_biz_no": issuerule_data.get("outer_source_id", f"issue_{institution_id}"),
|
|
|
+ "quota_id": issue_rule_id,
|
|
|
+ "total_amount": float(issuerule_data.get("issue_amount_value", 0)),
|
|
|
+ "available_amount": float(issuerule_data.get("issue_amount_value", 0)),
|
|
|
+ "status": "QUOTA_ACTIVE",
|
|
|
+ "enterprise_id": enterprise_id,
|
|
|
+ }
|
|
|
+ try:
|
|
|
+ from sqlalchemy import insert
|
|
|
+ stmt = insert(QuotaModel).values(**quota_save_data)
|
|
|
+ await auth.db.execute(stmt)
|
|
|
+ await auth.db.flush()
|
|
|
+ except Exception as e:
|
|
|
+ log.warning(f"保存发放规则到本地失败: {e}")
|
|
|
+
|
|
|
return {
|
|
|
"institution_id": institution_id,
|
|
|
"scope_modified": scope_modified,
|
|
|
@@ -375,11 +423,16 @@ class InstitutionService:
|
|
|
|
|
|
@classmethod
|
|
|
async def modify_institution_service(
|
|
|
- cls, auth: AuthSchema, data: AlipayEbppInvoiceInstitutionModifyModel
|
|
|
+ cls, auth: AuthSchema, data: AlipayEbppInvoiceInstitutionModifyModel, raw_data: dict | None = None
|
|
|
) -> AlipayEbppInvoiceInstitutionModifyResponse:
|
|
|
"""
|
|
|
编辑费控制度
|
|
|
调用: alipay.ebpp.invoice.institution.modify
|
|
|
+
|
|
|
+ 支付宝成功后同步更新本地DB:
|
|
|
+ - 制度基本信息
|
|
|
+ - 使用规则(standard_info_list → pay_expense_rule)
|
|
|
+ - 额度(issuerule → pay_expense_quota)
|
|
|
"""
|
|
|
if data.institution_id is None:
|
|
|
raise CustomException(msg="编辑费控制度失败: 制度ID不能为空")
|
|
|
@@ -399,33 +452,136 @@ class InstitutionService:
|
|
|
log.error(f"支付宝接口调用失败: {result.code} - {result.msg}")
|
|
|
raise CustomException(msg=f"编辑费控制度失败: {result.msg}")
|
|
|
|
|
|
- # 同步更新本地数据库状态
|
|
|
+ # 同步更新本地数据库
|
|
|
+ institution_id = getattr(data, 'institution_id', None)
|
|
|
+ if not institution_id:
|
|
|
+ return result
|
|
|
+
|
|
|
try:
|
|
|
crud = InstitutionCRUD(auth)
|
|
|
- institution_id = getattr(data, 'institution_id', None)
|
|
|
- if institution_id:
|
|
|
- update_data = {}
|
|
|
- if hasattr(data, 'institution_name') and data.institution_name:
|
|
|
- update_data['institution_name'] = data.institution_name
|
|
|
- if hasattr(data, 'institution_desc') and data.institution_desc:
|
|
|
- update_data['institution_desc'] = data.institution_desc
|
|
|
- if hasattr(data, 'effective') and data.effective is not None:
|
|
|
- update_data['effective'] = data.effective
|
|
|
- update_data['status'] = (
|
|
|
- InstitutionStatusEnum.INSTITUTION_EFFECTIVE.value
|
|
|
- if data.effective == "1"
|
|
|
- else InstitutionStatusEnum.INSTITUTION_INVALID.value
|
|
|
+ update_data = {}
|
|
|
+ if hasattr(data, 'institution_name') and data.institution_name:
|
|
|
+ update_data['institution_name'] = data.institution_name
|
|
|
+ if hasattr(data, 'institution_desc') and data.institution_desc:
|
|
|
+ update_data['institution_desc'] = data.institution_desc
|
|
|
+ if hasattr(data, 'effective') and data.effective is not None:
|
|
|
+ update_data['effective'] = data.effective
|
|
|
+ update_data['status'] = (
|
|
|
+ InstitutionStatusEnum.INSTITUTION_EFFECTIVE.value
|
|
|
+ if data.effective == "1"
|
|
|
+ else InstitutionStatusEnum.INSTITUTION_INVALID.value
|
|
|
+ )
|
|
|
+ if hasattr(data, 'effective_start_date') and data.effective_start_date:
|
|
|
+ update_data['effective_start_date'] = data.effective_start_date
|
|
|
+ if hasattr(data, 'effective_end_date') and data.effective_end_date:
|
|
|
+ update_data['effective_end_date'] = data.effective_end_date
|
|
|
+
|
|
|
+ if update_data:
|
|
|
+ await crud.update_by_institution_id(institution_id, update_data)
|
|
|
+ log.info(f"已更新本地制度: institution_id={institution_id}")
|
|
|
+
|
|
|
+ # 同步标准规则(modify_standard_detail_info)
|
|
|
+ std_detail = (raw_data or {}).get("modify_standard_detail_info") or {}
|
|
|
+ if std_detail:
|
|
|
+ from app.plugin.module_payment.expense.rule.model import ExpenseRuleModel
|
|
|
+ from sqlalchemy import delete as sa_delete
|
|
|
+
|
|
|
+ # 删除规则
|
|
|
+ delete_ids = std_detail.get("delete_standard_id_list", [])
|
|
|
+ if delete_ids:
|
|
|
+ d_stmt = sa_delete(ExpenseRuleModel).where(
|
|
|
+ ExpenseRuleModel.rule_id.in_(delete_ids)
|
|
|
+ )
|
|
|
+ await auth.db.execute(d_stmt)
|
|
|
+
|
|
|
+ # 新增规则
|
|
|
+ add_list = std_detail.get("add_standard_list", [])
|
|
|
+ from sqlalchemy import insert as sa_insert
|
|
|
+ for std in add_list:
|
|
|
+ ins_data = {
|
|
|
+ "out_biz_no": std.get("outer_source_id", f"std_{institution_id}"),
|
|
|
+ "institution_id": institution_id,
|
|
|
+ "rule_id": std.get("standard_id"),
|
|
|
+ "standard_name": std.get("standard_name"),
|
|
|
+ "standard_desc": std.get("standard_desc"),
|
|
|
+ "expense_type_sub_category": std.get("expense_type_sub_category", "DEFAULT"),
|
|
|
+ "enterprise_id": raw_data.get("enterprise_id", ""),
|
|
|
+ }
|
|
|
+ stmt = sa_insert(ExpenseRuleModel).values(**ins_data)
|
|
|
+ await auth.db.execute(stmt)
|
|
|
+
|
|
|
+ # 修改规则
|
|
|
+ modify_list = std_detail.get("modify_standard_list", [])
|
|
|
+ for std in modify_list:
|
|
|
+ std_id = std.get("standard_id", "").strip('"')
|
|
|
+ update_std = {}
|
|
|
+ if std.get("standard_name"):
|
|
|
+ update_std["standard_name"] = std["standard_name"]
|
|
|
+ if std.get("standard_desc"):
|
|
|
+ update_std["standard_desc"] = std["standard_desc"]
|
|
|
+ if update_std and std_id:
|
|
|
+ from sqlalchemy import update as sa_update
|
|
|
+ u_stmt = sa_update(ExpenseRuleModel).where(
|
|
|
+ ExpenseRuleModel.rule_id == std_id
|
|
|
+ ).values(**update_std)
|
|
|
+ await auth.db.execute(u_stmt)
|
|
|
+
|
|
|
+ await auth.db.flush()
|
|
|
+ log.info(f"已同步使用规则: institution_id={institution_id}")
|
|
|
+
|
|
|
+ # 同步发放规则(modify_issue_rule_detail_info)
|
|
|
+ issue_detail = (raw_data or {}).get("modify_issue_rule_detail_info") or {}
|
|
|
+ if issue_detail:
|
|
|
+ from app.plugin.module_payment.expense.quota.model import QuotaModel
|
|
|
+ from sqlalchemy import delete as sa_delete
|
|
|
+
|
|
|
+ # 删除发放规则
|
|
|
+ delete_ids = issue_detail.get("delete_issue_rule_id_list", [])
|
|
|
+ if delete_ids:
|
|
|
+ d_stmt = sa_delete(QuotaModel).where(
|
|
|
+ QuotaModel.quota_id.in_(delete_ids)
|
|
|
)
|
|
|
- if hasattr(data, 'effective_start_date') and data.effective_start_date:
|
|
|
- update_data['effective_start_date'] = data.effective_start_date
|
|
|
- if hasattr(data, 'effective_end_date') and data.effective_end_date:
|
|
|
- update_data['effective_end_date'] = data.effective_end_date
|
|
|
-
|
|
|
- if update_data:
|
|
|
- await crud.update_by_institution_id(institution_id, update_data)
|
|
|
- log.info(f"已更新本地记录: institution_id={institution_id}")
|
|
|
+ await auth.db.execute(d_stmt)
|
|
|
+
|
|
|
+ # 新增发放规则
|
|
|
+ add_list = issue_detail.get("add_issue_rule_list", [])
|
|
|
+ for rule in add_list:
|
|
|
+ amount = float(rule.get("issue_amount_value", 0))
|
|
|
+ ins_data = {
|
|
|
+ "employee_id": "",
|
|
|
+ "institution_id": institution_id,
|
|
|
+ "out_biz_no": rule.get("outer_source_id", f"issue_{institution_id}"),
|
|
|
+ "quota_id": rule.get("issue_rule_id"),
|
|
|
+ "total_amount": amount,
|
|
|
+ "available_amount": amount,
|
|
|
+ "status": "QUOTA_ACTIVE",
|
|
|
+ "enterprise_id": raw_data.get("enterprise_id", ""),
|
|
|
+ }
|
|
|
+ stmt = sa_insert(QuotaModel).values(**ins_data)
|
|
|
+ await auth.db.execute(stmt)
|
|
|
+
|
|
|
+ # 修改发放规则
|
|
|
+ modify_rule = issue_detail.get("modify_issue_rule_list") or {}
|
|
|
+ if modify_rule.get("issue_rule_id"):
|
|
|
+ q_id = modify_rule["issue_rule_id"].strip('"')
|
|
|
+ update_q = {}
|
|
|
+ if modify_rule.get("issue_amount_value"):
|
|
|
+ update_q["total_amount"] = float(modify_rule["issue_amount_value"])
|
|
|
+ update_q["available_amount"] = float(modify_rule["issue_amount_value"])
|
|
|
+ if modify_rule.get("issue_rule_name"):
|
|
|
+ update_q["standard_name"] = modify_rule["issue_rule_name"]
|
|
|
+ if update_q and q_id:
|
|
|
+ from sqlalchemy import update as sa_update
|
|
|
+ u_stmt = sa_update(QuotaModel).where(
|
|
|
+ QuotaModel.quota_id == q_id
|
|
|
+ ).values(**update_q)
|
|
|
+ await auth.db.execute(u_stmt)
|
|
|
+
|
|
|
+ await auth.db.flush()
|
|
|
+ log.info(f"已同步发放规则: institution_id={institution_id}")
|
|
|
+
|
|
|
except Exception as e:
|
|
|
- log.warning(f"更新本地记录失败(不影响支付宝侧): {e}")
|
|
|
+ log.warning(f"本地同步失败(不影响支付宝侧): {e}")
|
|
|
|
|
|
return result
|
|
|
|