153 lines
7.9 KiB
Python
153 lines
7.9 KiB
Python
from odoo import models, fields, api
|
||
|
||
# 待付提醒收件人的判定条件:辅助角色「出纳 (财务部)」+ 该角色所属公司「天河智城」
|
||
# (soong.user.role 的显示名 = 角色名称 + (所属部门),所以「出纳 (财务部)」= 角色名出纳 + 部门财务部)
|
||
PAYABLE_REMINDER_COMPANY = '天河智城' # 角色所属公司
|
||
PAYABLE_REMINDER_ROLE = '出纳' # 角色名称
|
||
PAYABLE_REMINDER_DEPARTMENT = '财务部' # 角色所属部门
|
||
|
||
|
||
class PropertyBillsList(models.Model):
|
||
_name = 'property.bills.list'
|
||
_description = '应付账单'
|
||
|
||
name = fields.Char(string="标题")
|
||
management_type_id = fields.Many2one('yuthon.management.type', string='类型')
|
||
due_date = fields.Date(string='应付日期')
|
||
actual_date = fields.Date(string='实付日期')
|
||
amount = fields.Float(string='应付')
|
||
amount_actual = fields.Float(string='实付')
|
||
receivables_id = fields.Many2one('property.accounts.receivable', string='应收账单')
|
||
contract_id = fields.Many2one('property.lease.contract', string="合同编号")
|
||
lessor_id = fields.Many2one(related='contract_id.lessor_id', string="支付公司")
|
||
lessee_id = fields.Many2one(related="contract_id.lessee_id", string="承租方", store=True)
|
||
property_name = fields.Char(related='contract_id.property_name', string="物业信息")
|
||
workflow_record_id = fields.Many2one('soong.workflow.record', string="流程")
|
||
fee_id = fields.Many2one('property.fee.form', string="费用")
|
||
remake = fields.Text(string="备注")
|
||
pay_state = fields.Selection([('unpaid', '待付'), ('paid', '已付')], string="支付状态", default="unpaid")
|
||
|
||
def update_pay_state(self):
|
||
bills_ids = self.env["property.bills.list"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in bills_ids:
|
||
if record.actual_date:
|
||
record.pay_state = 'paid'
|
||
|
||
def update_lessor_id(self):
|
||
bills_ids = self.env["property.bills.list"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in bills_ids:
|
||
if record.contract_id:
|
||
record.lessor_id = record.contract_id.lessor_id.id
|
||
|
||
def open_record(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"res_model": self.workflow_record_id.res_model,
|
||
"res_id": self.workflow_record_id.res_id,
|
||
"name": self.workflow_record_id.name,
|
||
"view_mode": "form",
|
||
}
|
||
|
||
def open_record1(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"res_model": "property.fee.form",
|
||
"res_id": self.fee_id.id,
|
||
"view_mode": "form",
|
||
}
|
||
|
||
def action_pay(self):
|
||
return {
|
||
'name': '支付账单弹窗',
|
||
'type': 'ir.actions.act_window',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.bills.wizard',
|
||
'target': 'new',
|
||
'context': {
|
||
'default_receivables_id': self.receivables_id.id,
|
||
'default_bills_list_id': self.id,
|
||
}
|
||
}
|
||
|
||
# ======================================================================
|
||
# 定时提醒:每天早上10点,有待付账单就提醒「出纳(财务部)」及时处理
|
||
# 对应定时任务:data/property_bills_payable_cron.xml
|
||
# ======================================================================
|
||
|
||
@api.model
|
||
def _payable_reminder_employees(self):
|
||
"""取出待付提醒的收件人:辅助角色为「出纳 (财务部)」、且该角色属于天河智城 的员工"""
|
||
# 先定位角色:公司=天河智城 + 角色名=出纳 + 所属部门=财务部(三者合起来正是显示名「出纳 (财务部)」)
|
||
roles = self.env['soong.user.role'].sudo().search([
|
||
('company_id.name', '=', PAYABLE_REMINDER_COMPANY), # 角色所属公司
|
||
('name', '=', PAYABLE_REMINDER_ROLE), # 角色名称
|
||
('department_id.name', '=', PAYABLE_REMINDER_DEPARTMENT), # 角色所属部门
|
||
])
|
||
# 辅助角色字段(hr.employee.user_role_ids)包含上述角色的员工
|
||
return self.env['hr.employee'].sudo().search([('user_role_ids', 'in', roles.ids)])
|
||
|
||
@api.model
|
||
def _log_payable_reminder(self, message):
|
||
"""写一条运行日志到 ir.logging,便于在后台(设置-技术-日志)排查定时任务执行情况"""
|
||
self.env['ir.logging'].sudo().create({
|
||
'name': '应付账单待付提醒', # 日志来源
|
||
'type': 'server', # 服务端日志
|
||
'message': message, # 日志正文
|
||
'path': __name__, # 代码文件
|
||
'func': 'cron_send_payable_reminder', # 所属方法
|
||
'line': 0, # 行号占位
|
||
})
|
||
|
||
@api.model
|
||
def cron_send_payable_reminder(self):
|
||
"""定时任务(每天早上10点):存在待付账单时,给「出纳(财务部)」发企业微信消息提醒"""
|
||
# 取所有待付(pay_state=unpaid)的应付账单
|
||
bills = self.env['property.bills.list'].sudo().search([('pay_state', '=', 'unpaid')])
|
||
# 没有待付账单就不发提醒,记日志返回
|
||
if not bills:
|
||
self._log_payable_reminder('当前没有待付的应付账单,本次不发送提醒')
|
||
return True
|
||
# 收件人:辅助角色=出纳(财务部) 且 角色所属公司=天河智城 的员工
|
||
employees = self._payable_reminder_employees()
|
||
# 找不到收件人时记日志返回
|
||
if not employees:
|
||
self._log_payable_reminder('未找到「辅助角色=出纳 (财务部)、公司=天河智城」的员工,本次不发送提醒')
|
||
return True
|
||
# 消息卡片跳转地址:后台「应付账单」菜单
|
||
menu = self.sudo().env.ref('yuthon_work_brand.property_bills_payable_menu')
|
||
url = 'https://oa.thtzjt.com/web#cids=2&action=%s&model=property.bills.list&view_type=list&menu_id=%s' % (
|
||
menu.action.id, menu.id)
|
||
# 本次成功发送的条数
|
||
sent_count = 0
|
||
for employee in employees:
|
||
# 没有绑定企业微信 UserID 就推送不了,跳过并记日志
|
||
if not employee.wecom_userid:
|
||
self._log_payable_reminder('%s 未绑定企业微信,跳过提醒' % employee.name)
|
||
continue
|
||
try:
|
||
# 调用企业微信接口推送文本卡片消息
|
||
self.sudo().env['wecom.apps'].sync_send_message_textcard(
|
||
category='notice', # 走「通知公告消息通知」应用
|
||
user_id=employee.wecom_userid, # 收件人:员工的企微成员 UserID
|
||
title='应付账单待付提醒', # 卡片标题
|
||
description='%s,您有未处理的待付,请及时处理。' % (employee.name or ''), # 卡片正文
|
||
url=url, # 点击跳转地址
|
||
btntxt='详细信息', # 按钮文字
|
||
)
|
||
# 发送成功计数
|
||
sent_count += 1
|
||
# 记录成功日志
|
||
self._log_payable_reminder('已发送待付提醒给 %s' % employee.name)
|
||
except Exception as error:
|
||
# 单个收件人发送失败不影响其他收件人,记日志后继续
|
||
self._log_payable_reminder('发送待付提醒给 %s 失败:%s' % (employee.name, error))
|
||
# 记录本次整体发送结果
|
||
self._log_payable_reminder('应付账单待付提醒执行完成,共发送 %s 条' % sent_count)
|
||
return True
|
||
|
||
|
||
|
||
|