fix(审批邮件): items_json序列化Bug修复 + 邮件方法出库/借库物理隔离
This commit is contained in:
@ -136,7 +136,7 @@ class BorrowApprovalService:
|
||||
"""发送新借库申请通知邮件给审批人和申请人(静默处理,不阻断主流程)"""
|
||||
try:
|
||||
from flask import current_app
|
||||
from app.utils.email_service import send_new_request_notify
|
||||
from app.utils.email_service import send_borrow_new_request_notify
|
||||
from app.models.system import SysUser
|
||||
|
||||
applicant_name = ''
|
||||
@ -176,7 +176,7 @@ class BorrowApprovalService:
|
||||
# 4. 分别发送邮件
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_new_request_notify(
|
||||
send_borrow_new_request_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -189,7 +189,7 @@ class BorrowApprovalService:
|
||||
|
||||
if approver_emails:
|
||||
try:
|
||||
send_new_request_notify(
|
||||
send_borrow_new_request_notify(
|
||||
to_emails=approver_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -215,7 +215,7 @@ class BorrowApprovalService:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from app.utils.email_service import send_approval_result_notify, send_warehouse_dispatch_notify
|
||||
from app.utils.email_service import send_borrow_approval_result_notify, send_borrow_dispatch_notify
|
||||
from app.models.system import SysUser as SU
|
||||
|
||||
# 1. 提取申请人信息
|
||||
@ -229,17 +229,32 @@ class BorrowApprovalService:
|
||||
applicant_emails.append(user.email)
|
||||
|
||||
# 2. 提取物料明细
|
||||
items = approval.items_json if approval.items_json else []
|
||||
items = approval.get_items() if approval else []
|
||||
|
||||
# 3. 分支逻辑
|
||||
if action == 'approve':
|
||||
# 3.1 通知库管(带明细)
|
||||
# 3.1 通知申请人(审批已通过,明确告知结果)
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_borrow_approval_result_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
is_passed=True,
|
||||
reject_reason='',
|
||||
applicant_name=applicant_name
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"[Email] 通知申请人(通过)失败: {e}")
|
||||
else:
|
||||
logger.warning("[Email] 申请人无邮箱,无法发送审批通过通知")
|
||||
|
||||
# 3.2 通知库管(请备货)
|
||||
warehouse_role_codes = ['WAREHOUSE_MGR', 'OUTBOUND']
|
||||
warehouse_emails = BorrowApprovalService._get_emails_by_identifiers(role_codes=warehouse_role_codes)
|
||||
|
||||
if warehouse_emails:
|
||||
try:
|
||||
send_warehouse_dispatch_notify(
|
||||
send_borrow_dispatch_notify(
|
||||
to_emails=warehouse_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -247,24 +262,14 @@ class BorrowApprovalService:
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"[Email] 通知库管失败: {e}")
|
||||
|
||||
# 3.2 通知申请人(审批通过,带完整物料清单)
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_warehouse_dispatch_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
items=items
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"[Email] 通知申请人(通过)失败: {e}")
|
||||
else:
|
||||
logger.warning("[Email] 无库管角色邮箱,无法发送备货通知")
|
||||
|
||||
elif action == 'reject':
|
||||
# 3.3 通知申请人(已驳回)
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_approval_result_notify(
|
||||
send_borrow_approval_result_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
is_passed=False,
|
||||
|
||||
@ -709,7 +709,7 @@ class OutboundApprovalService:
|
||||
"""发送新申请通知邮件给审批人和申请人(静默处理,不阻断主流程)"""
|
||||
try:
|
||||
from flask import current_app
|
||||
from app.utils.email_service import send_new_request_notify
|
||||
from app.utils.email_service import send_outbound_new_request_notify
|
||||
from app.models.system import SysUser
|
||||
|
||||
applicant_name = ''
|
||||
@ -749,7 +749,7 @@ class OutboundApprovalService:
|
||||
# 4. 分别发送邮件
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_new_request_notify(
|
||||
send_outbound_new_request_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -762,7 +762,7 @@ class OutboundApprovalService:
|
||||
|
||||
if approver_emails:
|
||||
try:
|
||||
send_new_request_notify(
|
||||
send_outbound_new_request_notify(
|
||||
to_emails=approver_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -871,7 +871,7 @@ class OutboundApprovalService:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from app.utils.email_service import send_approval_result_notify, send_warehouse_dispatch_notify
|
||||
from app.utils.email_service import send_outbound_approval_result_notify, send_outbound_dispatch_notify
|
||||
from app.models.system import SysUser as SU
|
||||
|
||||
# 1. 提取申请人信息(供两个分支使用)
|
||||
@ -885,7 +885,7 @@ class OutboundApprovalService:
|
||||
applicant_emails.append(user.email)
|
||||
|
||||
# 2. 提取物料明细(供通过分支使用)
|
||||
items = approval.items_json if approval.items_json else []
|
||||
items = approval.get_items() if approval else []
|
||||
|
||||
# 3. 分支逻辑
|
||||
if action == 'approve':
|
||||
@ -895,7 +895,7 @@ class OutboundApprovalService:
|
||||
|
||||
if warehouse_emails:
|
||||
try:
|
||||
send_warehouse_dispatch_notify(
|
||||
send_outbound_dispatch_notify(
|
||||
to_emails=warehouse_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -907,7 +907,7 @@ class OutboundApprovalService:
|
||||
# 3.2 通知申请人(审批通过,带完整物料清单)
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_warehouse_dispatch_notify(
|
||||
send_outbound_dispatch_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
applicant_name=applicant_name,
|
||||
@ -920,7 +920,7 @@ class OutboundApprovalService:
|
||||
# 3.3 通知申请人(已驳回)
|
||||
if applicant_emails:
|
||||
try:
|
||||
send_approval_result_notify(
|
||||
send_outbound_approval_result_notify(
|
||||
to_emails=applicant_emails,
|
||||
request_no=approval.request_no,
|
||||
is_passed=False,
|
||||
|
||||
@ -118,24 +118,13 @@ def send_email(to_email: Union[str, List[str]], subject: str, content: str):
|
||||
logger.error(f"[Email] 发送邮件时发生未知异常: {e}")
|
||||
|
||||
|
||||
def send_new_request_notify(to_emails: List[str], request_no: str,
|
||||
def send_outbound_new_request_notify(to_emails: List[str], request_no: str,
|
||||
applicant_name: str = '', remark: str = '',
|
||||
items: list = None, is_applicant_notify: bool = False):
|
||||
"""
|
||||
通知审批人有新的出库申请单待审批(可附带物料清单)
|
||||
或通知申请人其申请已提交(is_applicant_notify=True 时)
|
||||
|
||||
Args:
|
||||
to_emails: 审批人邮箱列表
|
||||
request_no: 审批单号
|
||||
applicant_name: 申请人姓名
|
||||
remark: 申请备注
|
||||
items: 物料明细列表(可选)
|
||||
is_applicant_notify: True=通知申请人(标题:您的出库申请已提交),False=通知审批人(标题:您有一笔新的出库审批待处理)
|
||||
"""
|
||||
print(f"[DEBUG send_new_request_notify] 入参 items={items}, is_applicant_notify={is_applicant_notify}")
|
||||
|
||||
# 拼装物料表格
|
||||
rows = []
|
||||
rows.append("名称 | 规格 | 计划数量")
|
||||
rows.append("-" * 40)
|
||||
@ -194,21 +183,78 @@ https://172.16.0.198/outbound/approval
|
||||
send_email(to_emails, subject, content)
|
||||
|
||||
|
||||
def send_approval_result_notify(to_emails: List[str], request_no: str,
|
||||
def send_borrow_new_request_notify(to_emails: List[str], request_no: str,
|
||||
applicant_name: str = '', remark: str = '',
|
||||
items: list = None, is_applicant_notify: bool = False):
|
||||
"""
|
||||
通知审批人有新的借库申请单待审批(可附带物料清单)
|
||||
或通知申请人其申请已提交(is_applicant_notify=True 时)
|
||||
"""
|
||||
rows = []
|
||||
rows.append("名称 | 规格 | 计划数量")
|
||||
rows.append("-" * 40)
|
||||
if items:
|
||||
for item in items:
|
||||
name = item.get('name', '-') or '-'
|
||||
spec = item.get('spec_model', '-') or '-'
|
||||
qty = item.get('quantity', '-') or '-'
|
||||
rows.append(f"{name} | {spec} | {qty}")
|
||||
else:
|
||||
rows.append("(无物料明细)")
|
||||
|
||||
if is_applicant_notify:
|
||||
subject = f"【已提交】您的借库申请单 {request_no} 已提交"
|
||||
content = f"""您好,
|
||||
|
||||
您的借库申请单 {request_no} 已成功提交,等待审批。
|
||||
|
||||
申请单号:{request_no}
|
||||
申请人:{applicant_name or '未知'}
|
||||
备注说明:{remark or '无'}
|
||||
|
||||
物料清单如下:
|
||||
{chr(10).join(rows)}
|
||||
|
||||
---
|
||||
您可以点击下方链接查看申请状态:
|
||||
https://172.16.0.198/operation/borrow_apply
|
||||
---
|
||||
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
else:
|
||||
subject = f"【待审批】借库申请单 {request_no}"
|
||||
content = f"""您好,
|
||||
|
||||
您有一笔新的借库审批申请待处理:
|
||||
|
||||
申请单号:{request_no}
|
||||
申请人:{applicant_name or '未知'}
|
||||
备注说明:{remark or '无'}
|
||||
|
||||
物料清单如下:
|
||||
{chr(10).join(rows)}
|
||||
|
||||
---
|
||||
⚡ 快速通道:
|
||||
请点击下方链接直接进入系统审批:
|
||||
https://172.16.0.198/operation/borrow_approval
|
||||
---
|
||||
|
||||
请登录仓库管理系统进行审批。
|
||||
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
send_email(to_emails, subject, content)
|
||||
|
||||
|
||||
def send_outbound_approval_result_notify(to_emails: List[str], request_no: str,
|
||||
is_passed: bool, reject_reason: str = '',
|
||||
applicant_name: str = ''):
|
||||
"""
|
||||
通知审批结果
|
||||
|
||||
Args:
|
||||
to_emails: 收件人邮箱列表
|
||||
request_no: 审批单号
|
||||
is_passed: 是否通过(通过时发给库管,驳回时发给申请人)
|
||||
reject_reason: 驳回原因(仅 is_passed=False 时使用)
|
||||
applicant_name: 申请人姓名(仅驳回通知时使用)
|
||||
通知出库审批结果
|
||||
"""
|
||||
if is_passed:
|
||||
# ★ 发给申请人:告知已通过,去领料
|
||||
subject = f"【已通过】出库申请单 {request_no}"
|
||||
content = f"""{"尊敬的 " + applicant_name + ",您好" if applicant_name else "您好"},
|
||||
|
||||
@ -219,7 +265,6 @@ def send_approval_result_notify(to_emails: List[str], request_no: str,
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
else:
|
||||
# ★ 发给申请人:告知被驳回
|
||||
subject = f"【已驳回】出库申请单 {request_no}"
|
||||
content = f"""{"尊敬的 " + applicant_name + ",您好" if applicant_name else "您好"},
|
||||
|
||||
@ -234,19 +279,43 @@ def send_approval_result_notify(to_emails: List[str], request_no: str,
|
||||
send_email(to_emails, subject, content)
|
||||
|
||||
|
||||
def send_warehouse_dispatch_notify(to_emails: List[str], request_no: str,
|
||||
def send_borrow_approval_result_notify(to_emails: List[str], request_no: str,
|
||||
is_passed: bool, reject_reason: str = '',
|
||||
applicant_name: str = ''):
|
||||
"""
|
||||
通知借库审批结果
|
||||
"""
|
||||
if is_passed:
|
||||
subject = f"【已通过】借库申请单 {request_no}"
|
||||
content = f"""{"尊敬的 " + applicant_name + ",您好" if applicant_name else "您好"},
|
||||
|
||||
您的借库申请单 {request_no} 已审批通过,请前往仓库扫码借出。
|
||||
|
||||
请登录仓库管理系统查看详情。
|
||||
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
else:
|
||||
subject = f"【已驳回】借库申请单 {request_no}"
|
||||
content = f"""{"尊敬的 " + applicant_name + ",您好" if applicant_name else "您好"},
|
||||
|
||||
借库申请单 {request_no} 已被审批驳回。
|
||||
|
||||
驳回原因:{reject_reason or '未填写'}
|
||||
|
||||
请登录仓库管理系统查看详情,并根据驳回原因调整后重新提交申请。
|
||||
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
send_email(to_emails, subject, content)
|
||||
|
||||
|
||||
def send_outbound_dispatch_notify(to_emails: List[str], request_no: str,
|
||||
applicant_name: str = '', items: list = None):
|
||||
"""
|
||||
通知库管备货出库(包含完整物料清单)
|
||||
|
||||
Args:
|
||||
to_emails: 库管邮箱列表
|
||||
request_no: 审批单号
|
||||
applicant_name: 申请人姓名
|
||||
items: 物料明细列表,每个元素包含 name/spec_model/warehouse_location/quantity
|
||||
"""
|
||||
print(f"[DEBUG send_warehouse_dispatch_notify] 入参 items={items}")
|
||||
print(f"[DEBUG send_warehouse_dispatch_notify] items 类型={type(items)}, 长度={len(items) if items else 0}")
|
||||
print(f"[DEBUG send_outbound_dispatch_notify] 入参 items={items}")
|
||||
|
||||
rows = []
|
||||
rows.append("名称 | 规格 | 库位 | 计划数量")
|
||||
@ -275,4 +344,39 @@ def send_warehouse_dispatch_notify(to_emails: List[str], request_no: str,
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
send_email(to_emails, subject, content)
|
||||
print(f"DEBUG: 准备向服务器提交发信请求,收件人: {to_emails}")
|
||||
|
||||
|
||||
def send_borrow_dispatch_notify(to_emails: List[str], request_no: str,
|
||||
applicant_name: str = '', items: list = None):
|
||||
"""
|
||||
通知库管备货借库(包含完整物料清单)
|
||||
"""
|
||||
print(f"[DEBUG send_borrow_dispatch_notify] 入参 items={items}")
|
||||
|
||||
rows = []
|
||||
rows.append("名称 | 规格 | 库位 | 计划数量")
|
||||
rows.append("-" * 50)
|
||||
if items:
|
||||
for item in items:
|
||||
name = item.get('name', '-') or '-'
|
||||
spec = item.get('spec_model', '-') or '-'
|
||||
loc = item.get('warehouse_location', '-') or '-'
|
||||
qty = item.get('quantity', '-') or '-'
|
||||
rows.append(f"{name} | {spec} | {loc} | {qty}")
|
||||
else:
|
||||
rows.append("(无物料明细)")
|
||||
|
||||
subject = f"【待借库】借库申请单 {request_no} 已审批通过"
|
||||
content = f"""您好,
|
||||
|
||||
借库申请单 {request_no} 已审批通过,请按以下清单准备备货:
|
||||
|
||||
{chr(10).join(rows)}
|
||||
|
||||
申请人:{applicant_name or '未知'}
|
||||
|
||||
请登录仓库管理系统执行"扫码借库"操作。
|
||||
|
||||
此邮件由系统自动发送,请勿回复。
|
||||
"""
|
||||
send_email(to_emails, subject, content)
|
||||
|
||||
Reference in New Issue
Block a user