添加功能

This commit is contained in:
李鹏宇
2025-12-03 17:53:21 +08:00
parent 1b57a3657f
commit 9de957bae2
13 changed files with 155 additions and 91 deletions
+2
View File
@@ -68,6 +68,8 @@
'wizard/yuthon_delete_planning_wizard_views.xml',
'wizard/attendance_controls_wizard.xml',
'wizard/attendance_correct_wizard.xml',
'wizard/vacation_put_wizard_views.xml',
'wizard/vacation_confirm_wizard_views.xml',
'wizard/planning_slot_update_display_name_wizard.xml',
'wizard/yuthon_run_wizard.xml',
'views/applet_address_views.xml',
@@ -28,7 +28,7 @@
<field eval="False" name="doall"/>
</record>
<record forcecreate="True" id="yuthon_vacation_attendance_confirmation" model="ir.cron">
<field name="name">定时任务:发送我的考勤确认</field>
<field name="name">定时任务:批量发送考勤确认</field>
<field name="model_id" ref="model_yuthon_vacation_reports"/>
<field name="state">code</field>
<field name="code">model.attendance_confirmation()</field>
@@ -416,6 +416,7 @@ class HrAttendance(models.Model):
def revoke(self):
self.check_in = self.approval_check_in
self.correct_result = None
self.check_out = self.approval_check_out
self.is_no_card = self.is_approval_no
self.is_early_card = self.is_approval_early
@@ -405,63 +405,16 @@ class YuthonVacationReports(models.Model):
}
}
def button_all_put(self):
detail_ids = self.env["yuthon.vacation.reports"].browse(
self._context.get('active_ids', self._context.get('active_id'))
)
unique_employee_ids = list({detail.employee_id.id for detail in detail_ids if detail.employee_id})
for employee_id in unique_employee_ids:
# 筛选当前员工对应的考勤记录
employee_details = detail_ids.filtered(lambda d: d.employee_id.id == employee_id)
for detail in employee_details:
url = f'https://oa.thtzjt.com/webh5/#/vacation?id={detail.id}'
we_id = self.env['hr.employee'].browse(employee_id).wecom_userid
if we_id:
self.sudo().env["wecom.apps"].sync_send_message_textcard(
category='attendance',
user_id=we_id,
title="考勤确认",
description=f'{self.env["hr.employee"].browse(employee_id).name} 请确认你的考勤:',
url=url,
btntxt="详细信息"
)
def all_put(self):
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'type': 'success',
'message': '确认通知已发送',
'sticky': False,
}
'type': 'ir.actions.act_window',
'name': '批量发送确认弹窗',
'res_model': 'vacation.put.wizard',
'view_mode': 'form',
'target': 'new',
}
def attendance_confirmation(self):
reports = self.env["yuthon.vacation.reports"].search([('employee_id.name', '=', '叶华锋')])
if not reports:
return
#按员工分组,仅保留每个员工vacation_date最新的记录
employee_reports_map = {}
for report in reports:
if not report.employee_id:
continue
emp = report.employee_id
if emp not in employee_reports_map:
employee_reports_map[emp] = report
elif report.vacation_date > employee_reports_map[emp].vacation_date:
employee_reports_map[emp] = report
for employee, report in employee_reports_map.items():
url = f'https://oa.thtzjt.com/webh5/#/vacation?id={report.id}'
we_id = employee.wecom_userid
if we_id:
self.sudo().env["wecom.apps"].sync_send_message_textcard(
category='default',
user_id=we_id,
title="考勤确认",
description=f'{employee.name} 请确认你的考勤:',
url=url,
btntxt="详细信息"
)
def manage_confirmation(self):
vacation_ids = self.env["yuthon.vacation.reports"].browse(
@@ -662,11 +615,15 @@ class YuthonVacationReports(models.Model):
meal_total -= int(line.update_lines or 0)
record.meal_fee = meal_total
def batch_confirmation(self):
vacation_ids = self.env["yuthon.vacation.reports"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for rec in vacation_ids:
rec.vacation_state = 'confirmed'
def all_confirm(self):
return {
'name': '批量确认弹窗',
'type': 'ir.actions.act_window',
'res_model': 'vacation.confirm.wizard',
'view_mode': 'form',
'target': 'new',
}
# 自动确认考勤台账
def automatic_confirmation(self):
@@ -76,3 +76,6 @@ access_expatriation_approval,expatriation.approval,model_expatriation_approval,b
access_meal_approval,meal.approval,model_meal_approval,base.group_user,1,1,1,1
access_back_approval,back.approval,model_back_approval,base.group_user,1,1,1,1
access_staff_dining_report,staff.dining.report,model_staff_dining_report,base.group_user,1,1,1,1
access_vacation_confirm_wizard,vacation.confirm.wizard,model_vacation_confirm_wizard,base.group_user,1,1,1,1
access_vacation_put_wizard,vacation.put.wizard,model_vacation_put_wizard,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
76
77
78
79
80
81
@@ -283,13 +283,6 @@
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_hr_attendance_month_detail_tree1')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_hr_attendance.view_hr_attendance_month_detail_form1')})]"/>
</record>
<record id="all_data_attendance_put_month" model="ir.actions.server">
<field name="name">批量发送</field>
<field name="model_id" ref="yuthon_hr_attendance.model_hr_attendance_month_detail"/>
<field name="binding_model_id" ref="yuthon_hr_attendance.model_hr_attendance_month_detail"/>
<field name="state">code</field>
<field name="code">action = model.button_all_put()</field>
</record>
<!-- <record id="all_data_attendance_month_compute" model="ir.actions.server">-->
<!-- <field name="name">批量计算</field>-->
<!-- <field name="model_id" ref="yuthon_hr_attendance.model_hr_attendance_month_detail"/>-->
@@ -5,6 +5,10 @@
<field name="model">yuthon.vacation.reports</field>
<field name="arch" type="xml">
<tree string="假期额度记录" editable="bottom" edit="0" default_order="vacation_date desc">
<header>
<button name="all_put" type="object" string="批量发送" dclass="oe_highlight"/>
<button name="all_confirm" type="object" string="批量确认" dclass="oe_highlight"/>
</header>
<field name="vacation_state" widget="badge" decoration-info="vacation_state == 'unconfirmed'"
decoration-success="vacation_state == 'confirmed'"/>
<field name="employee_id" options="{'no_open': True}"/>
@@ -43,7 +47,6 @@
<field name="exam_leave" options='{ "fg_color": "white: exam_leave == False"}'/>
<button name="log" type="object" string="详情" class="oe_highlight"/>
<button name="button_put" string="发送" type="object" class="oe_highlight"/>
</tree>
</field>
</record>
@@ -474,13 +477,6 @@
<field name="binding_model_id" ref="yuthon_hr_attendance.model_yuthon_vacation_reports"/>
<field name="state">code</field>
<field name="code">action = model.update_vacation()</field>
</record>
<record id="all_data_attendance_put_month" model="ir.actions.server">
<field name="name">批量发送</field>
<field name="model_id" ref="yuthon_hr_attendance.model_yuthon_vacation_reports"/>
<field name="binding_model_id" ref="yuthon_hr_attendance.model_yuthon_vacation_reports"/>
<field name="state">code</field>
<field name="code">action = model.update_log()</field>
</record>
<record id="all_vacation_delete" model="ir.actions.server">
<field name="name">初始化日志</field>
@@ -496,13 +492,6 @@
<field name="state">code</field>
<field name="code">action = model.manage_confirmation()</field>
</record>
<record id="all_batch_confirmation" model="ir.actions.server">
<field name="name">批量确认</field>
<field name="model_id" ref="yuthon_hr_attendance.model_yuthon_vacation_reports"/>
<field name="binding_model_id" ref="yuthon_hr_attendance.model_yuthon_vacation_reports"/>
<field name="state">code</field>
<field name="code">action = model.batch_confirmation()</field>
</record>
<record id="all_update_vac" model="ir.actions.server">
<field name="name">一次性</field>
<field name="model_id" ref="yuthon_hr_attendance.model_yuthon_vacation_reports"/>
+2
View File
@@ -6,3 +6,5 @@ from . import attendance_controls_wizard
from . import attendance_correct_wizard
from . import yuthon_run_wizard
from . import planning_slot_update_display_name_wizard
from . import vacation_confirm_wizard
from . import vacation_put_wizard
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
import calendar
from odoo import models, api, fields, _
from odoo.tools.float_utils import float_round
from odoo.exceptions import ValidationError, UserError
from datetime import date
from datetime import timedelta
from datetime import datetime, time
class VacationConfirmWizard(models.TransientModel):
_name = 'vacation.confirm.wizard'
_description = '批量确认弹窗'
def action_confirm(self):
reports = self.env["yuthon.vacation.reports"].search([('vacation_state', '=', 'unconfirmed')])
for rec in reports:
rec.vacation_state = 'confirmed'
rec.automatic_confirmation()
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="vacation_confirm_wizard_form" model="ir.ui.view">
<field name="name">vacation.confirm.wizard.form</field>
<field name="model">vacation.confirm.wizard</field>
<field name="arch" type="xml">
<form string="批量确认弹窗">
<div>
确认要批量确认吗?
</div>
<footer>
<button string="确定" name="action_confirm" type="object" class="btn-primary"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>
@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
import calendar
from odoo import models, api, fields, _
from odoo.tools.float_utils import float_round
from odoo.exceptions import ValidationError, UserError
from datetime import date
from datetime import timedelta
from datetime import datetime, time
class VacationPutWizard(models.TransientModel):
_name = 'vacation.put.wizard'
_description = '批量发送弹窗'
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))
def _get_default_month(self):
current_month = datetime.now().month
return str(current_month)
def action_confirm(self):
year = int(self.select_year)
month = int(self.select_time)
vacation_date = datetime(year=year, month=month, day=1).date()
reports = self.env["yuthon.vacation.reports"].search([('vacation_state', '=', 'unconfirmed'),
('vacation_date', '=', vacation_date)
])
if not reports:
return
# 按员工分组,仅保留每个员工vacation_date最新的记录
employee_reports_map = {}
for report in reports:
if not report.employee_id:
continue
emp = report.employee_id
if emp not in employee_reports_map:
employee_reports_map[emp] = report
elif report.vacation_date > employee_reports_map[emp].vacation_date:
employee_reports_map[emp] = report
for employee, report in employee_reports_map.items():
url = f'https://oa.thtzjt.com/webh5/#/vacation?id={report.id}'
we_id = employee.wecom_userid
if we_id:
self.sudo().env["wecom.apps"].sync_send_message_textcard(
category='default',
user_id=we_id,
title="考勤确认",
description=f'{employee.name} 请确认你的考勤:',
url=url,
btntxt="详细信息"
)
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="vacation_put_wizard_form" model="ir.ui.view">
<field name="name">vacation.put.wizard.form</field>
<field name="model">vacation.put.wizard</field>
<field name="arch" type="xml">
<form string="批量确认弹窗">
<div>
只针对未确认的考勤确认单台账,确定要发送吗?
</div>
<group>
<field name="select_year"/>
<field name="select_time"/>
</group>
<footer>
<button string="确定" name="action_confirm" type="object" class="btn-primary"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>
@@ -42,7 +42,7 @@ class PropertyStatementsWizard(models.Model):
remake = row[2].value
original_amount = row[3].value
your_own_account = row[6].value
cleaned_amount = original_amount.replace(',', '') # 移除逗号
cleaned_amount = original_amount.replace(',', '')
float_amount = float(cleaned_amount)
your_own_unit = self.classify_by_last_four(your_own_account)
sequence_number = row[5].value