From 019619ea0e70d4a4b23c7d40699d333cdb98f82f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?=
<9664676+pengyuthon@user.noreply.gitee.com>
Date: Sun, 18 Jan 2026 18:52:34 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../models/soong_workflow_record.py | 42 ++++++++-
.../views/soong_workflow_record.xml | 2 +-
.../wizard/soong_workflow_comment_wizard.py | 10 +--
yuthon_holiday/models/inherit_hr_leave.py | 26 ++++++
yuthon_hr_attendance/__manifest__.py | 2 +-
.../models/overtime_approval.py | 12 ---
.../models/yuthon_holiday_statement.py | 55 ++++++++----
.../models/yuthon_overtime_report.py | 34 -------
.../models/yuthon_vacation_reports.py | 90 +++++++++++++++++--
.../views/overtime_approval.xml | 26 ------
.../views/yuthon_holiday_statement.xml | 28 +++---
.../views/yuthon_overtime_report.xml | 25 ------
.../views/yuthon_vacation_reports_views.xml | 69 +++++++++++++-
yuthon_wechat/models/wecom_apps.py | 54 ++++++-----
yuthon_will_task/models/yuthon_will_task.py | 6 +-
yuthon_work_brand/views/hr_menus.xml | 10 +--
16 files changed, 304 insertions(+), 187 deletions(-)
delete mode 100644 yuthon_hr_attendance/models/yuthon_overtime_report.py
delete mode 100644 yuthon_hr_attendance/views/yuthon_overtime_report.xml
diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py
index c1dc7ccc9..2ae837280 100644
--- a/soong_workflow/models/soong_workflow_record.py
+++ b/soong_workflow/models/soong_workflow_record.py
@@ -16,10 +16,7 @@ class SoongWorkflowRecord(models.Model):
def get_workflow_count(self):
domain = [
- ('soong_state', 'in', ['to_do', 'active']),
- ('employee_ids.user_id', '=', self.env.user.id),
- ('users_ids', 'in', self.env.user.id),
- ('reclaim_state', '=', False)
+ ('is_to_do', '=', True),
]
return self.search_count(domain)
@@ -74,6 +71,43 @@ class SoongWorkflowRecord(models.Model):
# 人力资源流程的发生日期
workflow_happen_date = fields.Date(string="发生日期")
is_unlink = fields.Boolean(string="是否可删", compute='_compute_is_unlink')
+ is_to_do = fields.Boolean(
+ string="是否是待办流程",
+ compute='_compute_is_to_do',
+ search='_search_is_to_do',
+ )
+ @api.depends('employee_ids', 'soong_state', 'reclaim_state')
+ def _compute_is_to_do(self):
+ current_uid = self.env.user.id
+ for record in self:
+ record.is_to_do = False
+ condition1 = record.soong_state == 'to_do'
+ condition2 = not record.reclaim_state
+ condition3 = False
+ if record.employee_ids:
+ condition3 = current_uid in record.employee_ids.mapped('user_id.id')
+ if condition1 and condition2 and condition3:
+ record.is_to_do = True
+
+ def _search_is_to_do(self, operator, value):
+ current_uid = self.env.user.id
+ current_employee_ids = self.env['hr.employee'].search([
+ ('user_id', '=', current_uid)
+ ]).ids
+ base_domain = [
+ ('soong_state', '=', 'to_do'),
+ ('reclaim_state', '=', False),
+ ('employee_ids', 'in', current_employee_ids)
+ ]
+ if (operator == '=' and value) or (operator == '!=' and not value):
+ domain = base_domain
+ elif (operator == '=' and not value) or (operator == '!=' and value):
+ domain = ['!'] + base_domain
+ else:
+ domain = []
+ return domain
+
+
@api.depends_context('uid', 'company')
@api.depends('department_id', 'employee_ids')
diff --git a/soong_workflow/views/soong_workflow_record.xml b/soong_workflow/views/soong_workflow_record.xml
index 4e63e02c6..05c1326e8 100644
--- a/soong_workflow/views/soong_workflow_record.xml
+++ b/soong_workflow/views/soong_workflow_record.xml
@@ -317,7 +317,7 @@
soong.workflow.record
tree,kanban,search
{'header_search_default_approve_state': 1, 'header_search_default_to_do':1, 'check_employee': 1}
- [('users_ids', 'in', uid), ('reclaim_state', '=', False), ('soong_state', 'in', ['to_do', 'to_active'])]
+ [('is_to_do', '=', True)]
diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py
index cdbe495b0..593ac2e33 100644
--- a/soong_workflow/wizard/soong_workflow_comment_wizard.py
+++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py
@@ -450,10 +450,10 @@ class SoongWorkflowCommentWizard(models.TransientModel):
for employee in self.employee_ids:
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form'
- url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
+ url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
_logger.info(f"===================当前的url为{url}=============================")
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
- user_id=employee.wecom_userid,
+ user_id='18562027762',
title= record_id._description if 'Purchase Order' != record_id._description else '采购订单',
description="标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(
fields.Datetime.now() + timedelta(hours=8)),
@@ -695,7 +695,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
recipients = [emp for emp in employees]
for employee in recipients:
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form'
- url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
+ url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url)
if self.res_model == 'purchase.order':
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
user_id=employee.wecom_userid,
@@ -716,7 +716,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model={record_id._name}&view_type=form'
- url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
+ url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url)
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
if self.employee_ids:
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.employee_ids if employee.user_id]
@@ -839,7 +839,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')])
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model={record_id._name}&view_type=form'
- url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
+ url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url)
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
record = self.env[self.res_model].search([('id', '=', self.res_id)])
record.log_ids[-1].write({'is_active_operate': True,
diff --git a/yuthon_holiday/models/inherit_hr_leave.py b/yuthon_holiday/models/inherit_hr_leave.py
index 249d04a9d..bbb7ccd5d 100644
--- a/yuthon_holiday/models/inherit_hr_leave.py
+++ b/yuthon_holiday/models/inherit_hr_leave.py
@@ -553,6 +553,32 @@ class HolidaysRequestBatch(models.Model):
'text': f"请假审批"
})
+ overtime_records = self.env['vacation.over.line'].search([
+ ('employee_id', '=', self.users_id.employee_ids.id),
+ ('remaining_quantity', '>', 0),
+ ('is_void', '=', False),
+ ('text', '!=', '上月继承额度'),
+ ], order='start_time ASC')
+
+ remaining_deduct = hours
+ for record in overtime_records:
+ if remaining_deduct <= 0:
+ break
+ current_remaining = record.remaining_quantity
+ deduct_amount = min(remaining_deduct, current_remaining)
+ if remaining_deduct > current_remaining:
+ carry_state = 'partial'
+ else:
+ carry_state = 'completed'
+
+ record.write({
+ 'carry_forward_date': fields.Date.to_string(period_start),
+ 'carry_forward_quantity': deduct_amount,
+ 'carry_forward_state': carry_state,
+ })
+ remaining_deduct -= deduct_amount
+
+
def _create_annual_leave_line(self, period_start, leave_data, hours, period):
"""更新年假记录,使用小时作为单位(增加重复校验,避免重复创建)"""
report_month = date(period_start.year, period_start.month, 1)
diff --git a/yuthon_hr_attendance/__manifest__.py b/yuthon_hr_attendance/__manifest__.py
index c7bffb6be..926c78072 100644
--- a/yuthon_hr_attendance/__manifest__.py
+++ b/yuthon_hr_attendance/__manifest__.py
@@ -65,7 +65,7 @@
'views/hr_attendance_portal_templates.xml',
'views/meal_approval.xml',
'views/applet_address_views.xml',
- # 'views/yuthon_holiday_statement.xml',
+ 'views/yuthon_holiday_statement.xml',
'views/all_attendance_menu.xml',
'views/overtime_approval_inherit_header.xml',
diff --git a/yuthon_hr_attendance/models/overtime_approval.py b/yuthon_hr_attendance/models/overtime_approval.py
index 22b3e1bee..3cd374f93 100644
--- a/yuthon_hr_attendance/models/overtime_approval.py
+++ b/yuthon_hr_attendance/models/overtime_approval.py
@@ -48,18 +48,6 @@ class OvertimeApprovals(models.Model):
work_end = fields.Boolean(string="结束")
is_over = fields.Boolean(string="超过", compute="_compute_duration")
- carry_forward_date = fields.Date(string="结转日期")
- carry_forward_duration = fields.Float(string="结转时长")
- carry_forward_result = fields.Selection([('success', '成功'),('failed', '失败')], string='结转结果',)
- validity = fields.Char(string="有效期")
- carry_forward_state = fields.Selection([('pending', '待结转'),('completed', '已结转'), ('partial', '部分结转')
- ],string='结转状态',
- default='pending',
- )
- remaining_quantity = fields.Float(string='剩余数')
-
-
-
def action_print_overtime(self):
self.ensure_one()
return self.env.ref('yuthon_hr_attendance.action_overtime_approval_print').report_action(self)
diff --git a/yuthon_hr_attendance/models/yuthon_holiday_statement.py b/yuthon_hr_attendance/models/yuthon_holiday_statement.py
index cf838d605..c8965af07 100644
--- a/yuthon_hr_attendance/models/yuthon_holiday_statement.py
+++ b/yuthon_hr_attendance/models/yuthon_holiday_statement.py
@@ -2,24 +2,45 @@ from odoo import api, fields, models, tools, _
from datetime import datetime, time, timedelta
from odoo.exceptions import UserError
from datetime import date, timedelta
-
-class HolidayStatement(models.Model):
+class YuthonOvertimeReport(models.Model):
_name = 'yuthon.holiday.statement'
+
+class InheritHrLeave(models.Model):
+ _inherit = 'hr.leave'
_description = '请假情况'
- leave_approval_type = fields.Char(string="审批类型")
- gender = fields.Selection([('male', '男'),('female', '女'),], string='性别', required=True, default='male')
- leave_title = fields.Char(string="标题")
- leave_summary = fields.Char(string="摘要")
+ caption = fields.Char(string="标题", compute="_compute_application_reason")
employee_id = fields.Many2one('hr.employee', string="发起人")
- leave_start_date = fields.Char(string="开始时间")
- leave_end_date = fields.Char(string="结束时间")
- leave_duration = fields.Char(string="请假时长")
- leave_stats = fields.Char(string="请假统计")
- application_reason = fields.Char(string="申请原因")
- leave_start_time = fields.Datetime(string="发起时间")
- leave_end_time = fields.Datetime(string="最后操作时间")
- approval_state = fields.Selection([
- ('approved', '通过'),
- ('rejected', '未通过')
- ], string='审批状态')
\ No newline at end of file
+ leave_stats = fields.Char(string="请假统计", compute="_compute_leave_stats")
+ application_reason = fields.Char(string="申请原因", compute="_compute_application_reason")
+
+ @api.depends('batch_id', 'hour_batch_id')
+ def _compute_application_reason(self):
+ for rec in self:
+ if rec.batch_id:
+ rec.application_reason = rec.batch_id.text
+ rec.caption = rec.batch_id.name
+ elif rec.hour_batch_id:
+ rec.application_reason = rec.hour_batch_id.text
+ rec.caption = rec.hour_batch_id.name
+ else:
+ rec.application_reason = ''
+ rec.caption = ''
+
+ @api.depends('holiday_status_id', 'employee_id')
+ def _compute_leave_stats(self):
+ for record in self:
+ record.leave_stats = ""
+ current_year = datetime.now().year
+ start_of_year = f"{current_year}-01-01"
+ end_of_year = f"{current_year}-12-31"
+ leave_records = self.env['hr.leave'].search([
+ ('employee_id', '=', record.employee_id.id),
+ ('holiday_status_id', '=', record.holiday_status_id.id),
+ ('date_from', '>=', start_of_year),
+ ('date_from', '<=', end_of_year),
+ ('state', '=', 'validate'),
+ ])
+ total_days = sum(leave.number_of_days for leave in leave_records)
+ leave_type_name = record.holiday_status_id.name
+ record.leave_stats = f"本年内已请{leave_type_name}{total_days:.1f}天"
\ No newline at end of file
diff --git a/yuthon_hr_attendance/models/yuthon_overtime_report.py b/yuthon_hr_attendance/models/yuthon_overtime_report.py
deleted file mode 100644
index aaaf1134d..000000000
--- a/yuthon_hr_attendance/models/yuthon_overtime_report.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from odoo import api, fields, models, tools, _
-from datetime import datetime, time, timedelta
-from odoo.exceptions import UserError
-from datetime import date, timedelta
-
-
-class YuthonOvertimeReport(models.Model):
- _name = 'yuthon.overtime.report'
- _description = '加班情况'
-
- employee_id = fields.Many2one('hr.employee', string="员工")
- department_id = fields.Many2one('hr.department',string="部门")
- overtime_date = fields.Char(string="加班时间")
- carry_forward_date = fields.Date(string="结转日期")
- carry_forward_duration = fields.Float(string="结转时长")
- carry_forward_result = fields.Selection(
- selection=[
- ('success', '成功'),
- ('failed', '失败')
- ],
- string='结转结果',
- )
- validity = fields.Char(string="有效期")
- carry_forward_state = fields.Selection(
- selection=[
- ('pending', '待结转'),
- ('completed', '已结转'),
- ('partial', '部分结转')
- ],
- string='结转状态',
- default='pending',
- )
- remaining_quantity = fields.Float(string='剩余数')
-
diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
index 6981e615b..cb9cca8f3 100644
--- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py
+++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
@@ -86,7 +86,6 @@ class YuthonVacationReports(models.Model):
attendance_message_log_ids = fields.One2many('attendance.message.log', 'vacation_id')
admin_confirms = fields.Boolean(string="是否管理员确认")
-
vacation_state = fields.Selection(
selection=[
('not_sent', "未发送"),
@@ -931,7 +930,8 @@ class VacationOverline(models.Model):
_description = '加班明细'
vacation_id = fields.Many2one('yuthon.vacation.reports', string='关联假期额度记录')
- employee_id = fields.Many2one('hr.employee', string='员工')
+ employee_id = fields.Many2one('hr.employee', string='员工', compute='_compute_employee_id', store=True)
+ department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门")
workflow_record_id = fields.Many2one('soong.workflow.record', string='流程')
update_type= fields.Selection([('add', '增加'), ('reduce', '减少')], string='更新类型')
workday = fields.Float(string='工作日')
@@ -947,6 +947,57 @@ class VacationOverline(models.Model):
text = fields.Text(string='备注')
is_confirm = fields.Boolean(string="是否确认")
+ overtime_name = fields.Char(string="标题", compute="_compute_overtime", store=True)
+ start_time = fields.Datetime(string="开始时间", compute="_compute_overtime", store=True)
+ end_time = fields.Datetime(string="结束时间", compute="_compute_overtime", store=True)
+ carry_forward_date = fields.Date(string="结转日期")
+ duration = fields.Float(string="加班时长", compute="_compute_overtime", store=True)
+ carry_forward_quantity = fields.Float(string="结转时长")
+ validity = fields.Char(string="有效期")
+ carry_forward_state = fields.Selection([('pending', '待结转'),('completed', '已结转'), ('partial', '部分结转')
+ ],string='结转状态',
+ default='pending',
+ )
+ remaining_quantity = fields.Float(string='剩余数', compute="_compute_remaining_quantity", store=True)
+
+ def update_line(self):
+ over_ids = self.env["vacation.over.line"].browse(
+ self._context.get('active_ids', self._context.get('active_id')))
+ for rec in over_ids:
+ rec._compute_remaining_quantity()
+ rec._compute_overtime()
+ rec._compute_employee_id()
+
+ @api.depends('duration', 'carry_forward_quantity')
+ def _compute_remaining_quantity(self):
+ for rec in self:
+ rec.remaining_quantity = rec.duration - rec.carry_forward_quantity
+
+ @api.depends('vacation_id')
+ def _compute_employee_id(self):
+ for rec in self:
+ if rec.vacation_id:
+ rec.employee_id = rec.vacation_id.employee_id.id
+ elif not rec.employee_id:
+ rec.employee_id = False
+
+ @api.depends('workflow_record_id')
+ def _compute_overtime(self):
+ for rec in self:
+ if rec.workflow_record_id and rec.update_type == 'add':
+ res_model = rec.workflow_record_id.res_model
+ res_id = rec.workflow_record_id.res_id
+ overtime_id = rec.env[res_model].search([('id', '=', res_id)])
+ rec.overtime_name = overtime_id.name
+ rec.start_time = overtime_id.start_time
+ rec.end_time = overtime_id.end_time
+ rec.duration = overtime_id.duration
+ else:
+ rec.overtime_name = ''
+ rec.start_time = ''
+ rec.end_time = ''
+ rec.duration = 0
+
def action_void(self):
self.is_void = True
@@ -969,6 +1020,8 @@ class VacationOverline(models.Model):
if vals.get('update_type') == 'reduce' and vals.get('vacation_id'):
vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id'])
+ current_vacation_date = vacation_main.vacation_date
+ next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
deduct_workday = vals.get('workday', 0.0)
deduct_public = vals.get('public_holidays', 0.0)
deduct_workday_convert = deduct_workday / 8
@@ -983,8 +1036,6 @@ class VacationOverline(models.Model):
is_cross_year = False
# 计算下月1号并判断是否跨年
if vacation_main.vacation_date:
- current_vacation_date = vacation_main.vacation_date
- next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
is_cross_year = current_vacation_date.year != next_month_first_day.year
# 跨年场景
@@ -1006,31 +1057,52 @@ class VacationOverline(models.Model):
current_text = vals.get('text', '').strip()
if current_text != '上月额度继承':
vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id'])
+ current_vacation_date = vacation_main.vacation_date
+ next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
add_workday = vals.get('workday', 0.0)
add_public = vals.get('public_holidays', 0.0)
+ next_month_vacation = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', vacation_main.employee_id.id),
+ ('vacation_date', '=', next_month_first_day),
+ ('vacation_state', 'in', ['not_sent', 'pending']),
+ ], limit=1)
if vacation_main:
vacation_add_vals = {
'year_workday': vacation_main.year_workday + add_workday / 8,
'year_holiday': vacation_main.year_holiday + add_public / 8,
}
vacation_main.write(vacation_add_vals)
+ next_month_vacation = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', vacation_main.employee_id.id),
+ ('vacation_date', '=', next_month_first_day),
+ ('vacation_state', 'in', ['not_sent', 'pending']),
+ ], limit=1)
+
+ if next_month_vacation:
+ total_add_days = add_workday + add_public
+ inherit_vacation = self.env['vacation.over.line'].search([
+ ('vacation_id', '=', next_month_vacation.id),
+ ('text', '=', '上月额度继承'),
+ ], limit=1)
+ if inherit_vacation:
+ inherit_vacation.write({
+ 'year_workday': next_month_vacation.year_workday + add_workday / 8,
+ 'year_holiday': next_month_vacation.year_holiday + add_public / 8,
+ 'workday': inherit_vacation.workday + total_add_days
+ })
if vacation_main.vacation_date:
current_vacation_date = vacation_main.vacation_date
next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
# 必须是跨年才写入上年工作日
is_cross_year = current_vacation_date.year != next_month_first_day.year
- next_month_vacation = self.env['yuthon.vacation.reports'].search([
- ('employee_id', '=', vacation_main.employee_id.id),
- ('vacation_date', '=', next_month_first_day),
- ('vacation_state', 'in', ['not_sent', 'pending']),
- ], limit=1)
if is_cross_year:
next_month_deduct_vals = {
'last_workday': next_month_vacation.last_workday + add_workday / 8,
'last_holiday': next_month_vacation.last_holiday + add_public / 8,
}
next_month_vacation.write(next_month_deduct_vals)
+ next_month_vacation.previous_year = next_month_vacation.last_workday/8 + next_month_vacation.last_holiday / 8,
return super(VacationOverline, self).create(vals)
diff --git a/yuthon_hr_attendance/views/overtime_approval.xml b/yuthon_hr_attendance/views/overtime_approval.xml
index 9f3304b57..678fcbe18 100644
--- a/yuthon_hr_attendance/views/overtime_approval.xml
+++ b/yuthon_hr_attendance/views/overtime_approval.xml
@@ -15,7 +15,6 @@
overtime.approval
+
+ vacation.over.line.overtime.tree
+ vacation.over.line
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ vacation.over.line.overtime.search
+ vacation.over.line
+
+
+
+
+
+
+
+
+
+
+ 加班情况
+ vacation.over.line
+ tree
+ [('workflow_record_id','!=', False), ('update_type', '=', 'add')]
+
+
+
+
+ 触发计算逻辑
+
+
+ code
+ action = model.update_line()
+
误餐情况
yuthon.vacation.reports
tree
+ [('meal_fee', '!=', 0)]
{'search_default_group_by_employee_id': 1, 'search_default_group_by_vacation_month': True}
diff --git a/yuthon_wechat/models/wecom_apps.py b/yuthon_wechat/models/wecom_apps.py
index 40953572d..aa9f94bd8 100644
--- a/yuthon_wechat/models/wecom_apps.py
+++ b/yuthon_wechat/models/wecom_apps.py
@@ -343,45 +343,43 @@ class WeComApps(models.Model):
return False, result_data.get("errmsg", "")
@api.model
- def generate_oauth_login_url(self, target_url, category='default'):
+ def generate_oauth_login_url(self, target_url, user_id=None):
"""
- 生成企业微信OAuth登录链接,用于在企业微信消息中发送
-
+
+ user_id = record.employee_id.user_id.id if record.employee_id.user_id else None
+ url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, user_id=user_id)
+
+ 生成企业微信免登录链接,用于在企业微信消息中发送
+ 与 /wechat/login_by_user_id 接口联动
+
参数:
target_url: 登录成功后要跳转的目标URL(完整URL或相对路径)
-
+ user_id: 用户ID (res.users的id),必需参数
+
返回:
- OAuth登录链接URL
+ 免登录链接URL,格式: /wechat/login_by_user_id?user_id=xxx&redirect_url=xxx
"""
+ if not user_id:
+ _logger.warning("generate_oauth_login_url: user_id 参数未提供,无法生成免登录链接")
+ return target_url # 如果未提供user_id,返回原始URL
+
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
+
# 如果target_url不是完整URL,补全为完整URL
if not target_url.startswith('http'):
if target_url.startswith('/'):
target_url = f"{base_url}{target_url}"
else:
target_url = f"{base_url}/{target_url}"
- # 编码目标URL作为state参数
+
+ # 编码目标URL作为redirect_url参数
encoded_target_url = quote(target_url, safe='')
- # 编码回调URI
- redirect_uri = quote(f'{base_url}/wechat/login_by_code', safe='')
-
- # 企业微信OAuth参数
- if category == 'oa':
- agent_id = self.env['wecom.apps'].search([('name', '=', '审批消息通知')])['agent_id']
- appid = self.env['wecom.apps'].search([('name', '=', '审批消息通知')])['corpid']
- else:
- appid = 'wwc955c117b738b052'
- agent_id = '1000120'
-
- # 生成OAuth登录链接
- oauth_url = (
- f'https://open.weixin.qq.com/connect/oauth2/authorize?'
- f'appid={appid}&'
- f'redirect_uri={redirect_uri}&'
- f'response_type=code&'
- f'scope=snsapi_base&'
- f'state={encoded_target_url}&'
- f'agentid={agent_id}#wechat_redirect'
+
+ # 生成免登录链接,使用 /wechat/login_by_user_id 接口
+ login_url = (
+ f'{base_url}/wechat/login_by_user_id?'
+ f'user_id={user_id}&'
+ f'redirect_url={encoded_target_url}'
)
-
- return oauth_url
+
+ return login_url
diff --git a/yuthon_will_task/models/yuthon_will_task.py b/yuthon_will_task/models/yuthon_will_task.py
index dfe4620be..55ae3fef3 100644
--- a/yuthon_will_task/models/yuthon_will_task.py
+++ b/yuthon_will_task/models/yuthon_will_task.py
@@ -180,7 +180,8 @@ class YuthonWillTask(models.Model):
if minute1 == now.minute and hour1 == now.hour:
task.write({'task_state': 'done'})
will_id = task.yuthon_will_task_id
- for employee_id in will_id.employee_ids:
+ will_id.task_state = 'done'
+ for employee_id in task.employee_ids:
url = f'https://phone.thtzjt.com/phone/Schedule/{task.yuthon_will_task_id.id}/{employee_id.id}'
data_date = '时间:' + (task.reminder_time + timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S") + '\n'
data_name = "事项名称: " + task.yuthon_will_task_id.name + '\n'
@@ -303,4 +304,5 @@ class YuthonWillTask(models.Model):
'view_mode': 'tree',
'res_model': 'yuthon.dates.task',
'domain': [('yuthon_will_task_id', '=', self.id)],
- }
\ No newline at end of file
+ }
+
diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml
index bb78ba116..be6321482 100644
--- a/yuthon_work_brand/views/hr_menus.xml
+++ b/yuthon_work_brand/views/hr_menus.xml
@@ -170,11 +170,11 @@
parent="hr_attendance_root_board_menu"
action="yuthon_hr_attendance.action_overtime_approval_report"
sequence="15"/>
-
-
-
-
-
+