Files
gzth/yuthon_salary/models/yuthon_salary_party.py
2026-04-03 18:08:26 +08:00

312 lines
12 KiB
Python

from odoo import api, fields, models
from datetime import datetime
class YuthonSalaryParty(models.Model):
_name = 'yuthon.salary.party'
_description = '党费'
employee_id = fields.Many2one('hr.employee', string='姓名')
card = fields.Char(string='身份证')
fee = fields.Float(string='党费')
payment = fields.Float(string='补缴党费')
total_payment = fields.Float(string='合计缴费')
company_id = fields.Many2one(related='employee_id.company_id', string="公司")
select_time = fields.Selection([('1', '一月'), ('2', '二月'), ('3', '三月'), ('4', '四月'),
('5', '五月'), ('6', '六月'), ('7', '七月'), ('8', '八月'),
('9', '九月'), ('10', '十月'), ('11', '十一月'),
('12', '十二月')], string='月份',
default=lambda self: self._get_default_month())
select_year = fields.Selection(selection=[(str(i), str(i)) for i in range(2024, 2040)], string='年份',
default=lambda self: str(datetime.now().year))
party_state = fields.Selection([('to_do', '待发送'), ('done', '已发送')], string='状态', default='to_do')
toll_state = fields.Selection([
('to_do', '待缴'),
('done', '待复核确认'),
('paid', '已缴费'),
], string='缴费状态', default='to_do')
def toll_confirm(self):
# 员工确认已缴费,状态进入待复核确认
self.toll_state = 'done'
def action_party_review_confirm(self):
"""打开党费缴费复核确认弹窗,只对状态为待复核确认的记录生效"""
self.ensure_one()
if self.toll_state != 'done':
return
return {
'type': 'ir.actions.act_window',
'name': '复核确认',
'res_model': 'party.expenses.review.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'default_party_id': self.id,
},
}
def _get_default_month(self):
current_month = datetime.now().month
return str(current_month)
def send_party(self):
return {
'type': 'ir.actions.act_window',
'name': '党费提醒',
'view_mode': 'form',
'res_model': 'party.send.wizard',
'target': 'new',
'context': {'default_employee_ids': [(6, 0, [self.employee_id.id])],
'skip_party_month_onchange': True
},
}
def action_send_party_reminder(self):
"""单条记录的催缴按钮"""
self.ensure_one()
# 如果党费金额为0,则不发送提醒
if self.total_payment <= 0:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '提醒',
'message': '党费金额为0,无需发送提醒',
'type': 'info',
'sticky': False,
}
}
employee = self.employee_id
if not employee or not employee.user_id or not employee.wecom_userid:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '错误',
'message': '员工信息不完整,无法发送提醒',
'type': 'danger',
'sticky': False,
}
}
# 构建提醒内容
employee_name = employee.name or ''
description = (
f'【党费缴费提醒】亲爱的同事,{self.select_year}年{self.select_time}月党费明细已出,你的上月党费金额为{self.total_payment}元,'
f'请尽快核对并缴费到指定账户:44001580909059000222广州市天河投资集团有限公司(转账时请备注"姓名+{self.select_time}月党费")。'
f'有任何问题,随时找办公室小伙伴沟通呀!'
)
# 发送提醒
try:
self.sudo().env["wecom.apps"].sync_send_message_textcard(
category='can',
user_id=employee.wecom_userid,
title="党费缴费提醒",
description=description,
url=f'https://phone.thtzjt.com/phone/Communist/{employee.user_id.id}',
btntxt="详细信息",
)
# 发送后将状态改为已发送
self.write({'party_state': 'done'})
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '成功',
'message': '党费缴费提醒已发送',
'type': 'success',
'sticky': False,
}
}
except Exception as e:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '错误',
'message': f'发送提醒失败:{str(e)}',
'type': 'danger',
'sticky': False,
}
}
def action_batch_send_party_reminder(self):
"""批量催缴"""
# 查询所有缴费状态为待缴,状态为已发送的记录
parties = self.sudo().search([
('toll_state', '=', 'to_do'),
('party_state', '=', 'done'),
])
# 发送提醒
sent_count = 0
skipped_count = 0
failed_count = 0
for party in parties:
# 如果党费金额为0,则跳过
if party.total_payment <= 0:
skipped_count += 1
continue
employee = party.employee_id
if not employee or not employee.user_id or not employee.wecom_userid:
failed_count += 1
continue
# 构建提醒内容
employee_name = employee.name or ''
description = (
f'{employee_name},您尚有党费未缴纳,请及时登录系统查看并完成缴费,感谢配合。'
)
# 发送提醒
try:
self.sudo().env["wecom.apps"].sync_send_message_textcard(
category='can',
user_id=employee.wecom_userid,
title="缴纳党费提醒",
description=description,
url=f'https://phone.thtzjt.com/phone/Communist/{employee.user_id.id}',
btntxt="详细信息",
)
sent_count += 1
except Exception as e:
failed_count += 1
# 显示结果
message = f'成功发送 {sent_count} 条提醒,跳过 {skipped_count} 条(金额为0),失败 {failed_count} 条'
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '批量催缴完成',
'message': message,
'type': 'success',
'sticky': False,
}
}
def cron_send_monthly_party_reminder(self):
"""定时任务:每月第一个工作日发送党费缴费提醒"""
from datetime import datetime, timedelta
# 检查是否是工作日
today = datetime.now()
if today.weekday() >= 5: # 0-4是工作日,5-6是周末
# 记录日志
self.env['ir.logging'].sudo().create({
'name': '党费缴费提醒',
'type': 'server',
'message': f'今天{today.strftime("%Y-%m-%d")}是周末,跳过发送党费缴费提醒',
'path': __name__,
'func': 'cron_send_monthly_party_reminder',
'line': 0,
})
return True
# 计算上月的年份和月份
last_month = today - timedelta(days=today.day)
last_year = str(last_month.year)
last_month_num = str(last_month.month)
# 计算当前月的年份和月份
current_year = str(today.year)
current_month = str(today.month)
# 查询所有状态为待缴且待发送的党费记录
parties = self.sudo().search([
('toll_state', '=', 'to_do'),
('party_state', '=', 'to_do'),
('select_year', '=', last_year),
('select_time', '=', last_month_num),
])
# 按员工分组
employee_parties = {}
for party in parties:
if party.employee_id not in employee_parties:
employee_parties[party.employee_id] = party
# 发送提醒
sent_count = 0
for employee, party in employee_parties.items():
if not employee or not employee.user_id or not employee.wecom_userid:
continue
# 计算上月党费金额
last_month_amount = party.total_payment
# 构建提醒内容
employee_name = employee.name or ''
description = (
f'【党费缴费提醒】亲爱的同事,{last_year}年{last_month_num}月党费明细已出,你的上月党费金额为{last_month_amount}元,'
f'请尽快核对并缴费到指定账户:44001580909059000222广州市天河投资集团有限公司(转账时请备注"姓名+{last_month_num}月党费")。'
f'有任何问题,随时找办公室小伙伴沟通呀!'
)
# 发送提醒
try:
self.sudo().env["wecom.apps"].sync_send_message_textcard(
category='can',
user_id=employee.wecom_userid,
title="党费缴费提醒",
description=description,
url=f'https://phone.thtzjt.com/phone/Communist/{employee.user_id.id}',
btntxt="详细信息",
)
# 发送后将状态改为已发送
party.write({'party_state': 'done'})
sent_count += 1
# 记录日志
self.env['ir.logging'].sudo().create({
'name': '党费缴费提醒',
'type': 'server',
'message': f'已发送{last_year}年{last_month_num}月党费缴费提醒给{employee_name}',
'path': __name__,
'func': 'cron_send_monthly_party_reminder',
'line': 0,
})
except Exception as e:
self.env['ir.logging'].sudo().create({
'name': '党费缴费提醒',
'type': 'server',
'message': f'发送{last_year}年{last_month_num}月党费缴费提醒给{employee_name}失败:{str(e)}',
'path': __name__,
'func': 'cron_send_monthly_party_reminder',
'line': 0,
})
# 记录总发送情况
self.env['ir.logging'].sudo().create({
'name': '党费缴费提醒',
'type': 'server',
'message': f'成功发送{sent_count}条{last_year}年{last_month_num}月党费缴费提醒',
'path': __name__,
'func': 'cron_send_monthly_party_reminder',
'line': 0,
})
return True
def action_test_monthly_party_reminder(self):
"""手动测试月度提醒"""
# 调用定时任务方法
result = self.cron_send_monthly_party_reminder()
# 显示成功通知
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '测试完成',
'message': '月度提醒测试已执行,请查看日志确认结果',
'type': 'success',
'sticky': False,
}
}