from datetime import datetime from typing import Optional from pydantic import BaseModel, ConfigDict, Field class IssueQuotaTargetSchema(BaseModel): """发放明细""" owner_type: str = Field( description="owner类型: EMPLOYEE(支付宝id)/PHONE(手机号)/ENTERPRISE_PAY_UID(员工企业码id)" ) owner_id: str = Field(description="owner ID") quota: float = Field(description="发放额度") amount: Optional[float] = Field(default=None, description="面额") class ExpenseQuotaCreateSchema(BaseModel): """创建余额/点券请求 (alipay.ebpp.invoice.expensecontrol.quota.create)""" target_type: str = Field( description="额度维度 (必填): INSTITUTION(制度维度)/EXPENSE_TYPE(费用类型维度)" ) target_id: str = Field(description="额度维度ID (必填)") enterprise_id: str = Field(description="企业ID (必填)") effective_start_date: Optional[datetime] = Field(default=None, description="额度生效时间") effective_end_date: Optional[datetime] = Field(default=None, description="额度失效时间") outer_source_id: Optional[str] = Field(default=None, description="外部幂等id") quota_type: Optional[str] = Field( default="CAP", description="额度类型: COUPON(点券)/CAP(余额)/COUNT(次卡)" ) share_mode: Optional[str] = Field( default="0", description="是否可转增: 0(不可转增)/1(可转增)" ) issue_name: Optional[str] = Field(default=None, max_length=20, description="发放名称") issue_desc: Optional[str] = Field(default=None, max_length=200, description="发放描述") issue_quota_target_list: Optional[list[IssueQuotaTargetSchema]] = Field( default=None, description="发放明细列表" ) class QuotaCreateSchema(BaseModel): """创建额度请求 (本地)""" employee_id: str = Field(description="员工ID") institution_id: str = Field(description="制度ID") total_amount: float = Field(description="总金额") available_amount: Optional[float] = Field(default=None, description="可用金额") valid_from: Optional[datetime] = Field(default=None, description="有效期开始") valid_to: Optional[datetime] = Field(default=None, description="有效期结束") class QuotaUpdateSchema(BaseModel): """更新额度请求""" total_amount: Optional[float] = Field(default=None, description="总金额") available_amount: Optional[float] = Field(default=None, description="可用金额") valid_from: Optional[datetime] = Field(default=None, description="有效期开始") valid_to: Optional[datetime] = Field(default=None, description="有效期结束") class ExpenseQuotaModifySchema(BaseModel): """修改余额/点券请求 (alipay.ebpp.invoice.expensecontrol.quota.modify)""" quota_id: str = Field(description="额度ID (必填)") action: str = Field( description="变更模式 (必填): ADD(增加额度)/DEDUCT(减少额度)/MODIFY_SHARE_MODE(修改转赠属性)" ) outer_source_id: str = Field(description="外部操作幂等ID (必填)") enterprise_id: str = Field(description="企业ID (必填)") amount: Optional[float] = Field(default=None, description="变更金额") share_mode: Optional[str] = Field( default=None, description="是否可转增: 0(不可转增)/1(可转增)" ) class ExpenseQuotaDeleteSchema(BaseModel): """删除额度请求 (alipay.ebpp.invoice.expensecontrol.quota.delete)""" enterprise_id: str = Field(description="企业ID (必填)") quota_id: Optional[str] = Field(default=None, description="额度ID") issue_batch_id: Optional[str] = Field(default=None, description="发放批次ID") class ExpenseQuotaQuerySchema(BaseModel): """查询余额/点券请求""" owner_type: str = Field( description="额度所属者类型 (必填): EMPLOYEE(支付宝id)/ENTERPRISE_PAY_UID(企业码id)/PHONE(手机号)" ) page_size: int = Field(default=20, description="每页条数") page_num: int = Field(default=1, description="页码") target_type: Optional[str] = Field( default=None, description="额度维度: EXPENSE_TYPE/RULE_GROUP_AGGREGATION/INSTITUTION" ) target_id: Optional[str] = Field(default=None, description="额度维度ID") owner_id: Optional[str] = Field(default=None, description="额度所属者ID") owner_open_id: Optional[str] = Field(default=None, description="额度所属者开放ID") enterprise_id: Optional[str] = Field(default=None, description="企业ID") quota_id_list: Optional[list[str]] = Field(default=None, description="额度ID列表") quota_type: Optional[str] = Field(default=None, description="额度类型: COUPON/CAP") class QuotaDetailInfoSchema(BaseModel): """额度详细信息""" quota_id: Optional[str] = Field(default=None, description="额度ID") target_type: Optional[str] = Field(default=None, description="额度维度") target_id: Optional[str] = Field(default=None, description="额度维度ID") quota_type: Optional[str] = Field(default=None, description="额度类型") owner_type: Optional[str] = Field(default=None, description="额度所属者类型") owner_id: Optional[str] = Field(default=None, description="额度所属者ID") owner_open_id: Optional[str] = Field(default=None, description="额度所属者开放ID") total_amount: Optional[float] = Field(default=None, description="总金额") available_amount: Optional[float] = Field(default=None, description="可用金额") frozen_amount: Optional[float] = Field(default=None, description="冻结金额") consumed_amount: Optional[float] = Field(default=None, description="已消费金额") effective_start_date: Optional[str] = Field(default=None, description="生效开始时间") effective_end_date: Optional[str] = Field(default=None, description="生效结束时间") status: Optional[str] = Field(default=None, description="状态") class ExpenseQuotaQueryOutSchema(BaseModel): """查询余额/点券响应""" page_size: int = Field(description="每页条数") page_num: int = Field(description="页码") total_page_count: int = Field(description="总页数") total_count: Optional[int] = Field(default=None, description="总记录数") quota_detail_info_list: Optional[list[QuotaDetailInfoSchema]] = Field( default=None, description="额度详细信息列表" ) class QuotaOutSchema(BaseModel): """额度响应模型""" model_config = ConfigDict(from_attributes=True) id: int = Field(description="主键ID") quota_id: Optional[str] = Field(default=None, description="额度ID") target_type: Optional[str] = Field(default=None, description="额度维度") target_id: Optional[str] = Field(default=None, description="额度维度ID") quota_type: Optional[str] = Field(default=None, description="额度类型") employee_id: Optional[str] = Field(default=None, description="员工ID") institution_id: Optional[str] = Field(default=None, description="制度ID") out_biz_no: Optional[str] = Field(default=None, description="外部业务编号") total_amount: Optional[float] = Field(default=None, description="总金额") available_amount: Optional[float] = Field(default=None, description="可用金额") frozen_amount: Optional[float] = Field(default=None, description="冻结金额") valid_from: Optional[datetime] = Field(default=None, description="有效期开始") valid_to: Optional[datetime] = Field(default=None, description="有效期结束") status: str = Field(description="状态") created_time: Optional[datetime] = Field(default=None, description="创建时间") updated_time: Optional[datetime] = Field(default=None, description="更新时间") class QuotaListOutSchema(BaseModel): """额度列表响应""" model_config = ConfigDict(from_attributes=True) id: int = Field(description="主键ID") quota_id: Optional[str] = Field(default=None, description="额度ID") target_type: Optional[str] = Field(default=None, description="额度维度") target_id: Optional[str] = Field(default=None, description="额度维度ID") quota_type: Optional[str] = Field(default=None, description="额度类型") employee_id: Optional[str] = Field(default=None, description="员工ID") institution_id: Optional[str] = Field(default=None, description="制度ID") total_amount: Optional[float] = Field(default=None, description="总金额") available_amount: Optional[float] = Field(default=None, description="可用金额") status: str = Field(description="状态") created_time: Optional[datetime] = Field(default=None, description="创建时间") class QuotaOperationOutSchema(BaseModel): """额度操作响应""" model_config = ConfigDict(from_attributes=True) out_biz_no: Optional[str] = Field(default=None, description="外部业务编号") quota_id: Optional[str] = Field(default=None, description="额度ID") result: Optional[bool] = Field(default=None, description="操作结果") # ======================== # 手工批量发放额度 (issuebatch) # ======================== class IssueTargetInfoSchema(BaseModel): """手工发放 - 员工发放信息""" issue_quota: str = Field(description="发放额度(单位: 元)") owner_open_id: Optional[str] = Field(default=None, description="员工开放ID") owner_id: Optional[str] = Field(default=None, description="员工ID") user_name: Optional[str] = Field(default=None, description="员工姓名") owner_type: Optional[str] = Field(default=None, description="owner类型: PHONE/EMPLOYEE/ENTERPRISE_PAY_UID") class IssueBatchCreateSchema(BaseModel): """手工批量发放额度请求 (alipay.ebpp.invoice.expensecontrol.issuebatch.create)""" enterprise_id: str = Field(description="企业ID") issue_name: str = Field(max_length=20, description="发放名称") quota_type: str = Field(description="额度类型: 只能填写COUPON") effective_start_date: str = Field(description="额度有效起始时间 (yyyy-MM-dd HH:mm:ss)") effective_end_date: str = Field(description="额度有效结束时间") institution_id: str = Field(description="制度ID") batch_no: str = Field(description="发放批次号(用于幂等校验, 必须是数字)") share_mode: str = Field(default="0", description="是否可转赠: 0(不可转赠)/1(可转赠)") issue_desc: Optional[str] = Field(default=None, max_length=200, description="发放说明") issue_target_info_list: Optional[list[IssueTargetInfoSchema]] = Field( default=None, description="员工发放信息列表(最多1000条)" ) class IssueQuotaCheckFailedItem(BaseModel): """批量发放校验失败项""" user_name: Optional[str] = Field(default=None, description="员工姓名") owner_type: Optional[str] = Field(default=None, description="owner类型") owner_id: Optional[str] = Field(default=None, description="员工ID") owner_open_id: Optional[str] = Field(default=None, description="员工开放ID") issue_quota: Optional[str] = Field(default=None, description="发放额度") message: Optional[str] = Field(default=None, description="失败原因") result: Optional[bool] = Field(default=None, description="是否成功") class IssueBatchCreateOutSchema(BaseModel): """手工批量发放额度响应""" issue_batch_id: Optional[str] = Field(default=None, description="发放批次ID") issue_quota_check_failed_list: Optional[list[IssueQuotaCheckFailedItem]] = Field( default=None, description="校验失败的数据" ) class IssueBatchCancelSchema(BaseModel): """手工批量发放作废请求 (alipay.ebpp.invoice.expensecontrol.issuebatch.cancel)""" enterprise_id: str = Field(description="企业ID") institution_id: str = Field(description="制度ID") issue_batch_id: str = Field(description="发放批次ID") class IssueBatchCancelOutSchema(BaseModel): """手工批量发放作废响应""" result: bool = Field(description="是否成功") class IssueBatchRecordsQuerySchema(BaseModel): """手工发放发放明细分页查询请求 (alipay.ebpp.invoice.issuebatch.issuerecords.batchquery)""" enterprise_id: str = Field(description="企业ID") institution_id: str = Field(description="制度ID") issue_batch_id: str = Field(description="发放批次ID") page_size: int = Field(default=20, description="页大小(最大100)") page_num: int = Field(default=1, description="页码") class IssueRecordInfoItem(BaseModel): """发放记录信息""" quota_id: Optional[str] = Field(default=None, description="额度ID") issue_quota: Optional[str] = Field(default=None, description="发放额度") issue_status: Optional[int] = Field(default=None, description="发放状态") owner_type: Optional[str] = Field(default=None, description="owner类型") owner_id: Optional[str] = Field(default=None, description="员工ID") owner_open_id: Optional[str] = Field(default=None, description="员工开放ID") user_name: Optional[str] = Field(default=None, description="员工姓名") currency: Optional[str] = Field(default=None, description="币种") class IssueBatchRecordsQueryOutSchema(BaseModel): """手工发放发放明细分页查询响应""" page_num: int = Field(description="页码") page_size: int = Field(description="页大小") total_page_count: str = Field(default="0", description="总页数") issue_record_info_list: Optional[list[IssueRecordInfoItem]] = Field( default=None, description="发放记录信息列表" ) class IssueBatchListOutSchema(BaseModel): """手工发放批次列表响应""" model_config = ConfigDict(from_attributes=True) id: int = Field(description="主键ID") issue_batch_id: Optional[str] = Field(default=None, description="发放批次ID") batch_no: str = Field(description="发放批次号") institution_id: str = Field(description="制度ID") issue_name: str = Field(description="发放名称") quota_type: str = Field(description="额度类型") share_mode: str = Field(description="是否可转赠") total_count: int = Field(description="发放总人数") total_amount: Optional[float] = Field(default=None, description="发放总金额") status: str = Field(description="状态") created_time: Optional[datetime] = Field(default=None, description="创建时间") updated_time: Optional[datetime] = Field(default=None, description="更新时间")