添加功能
This commit is contained in:
@@ -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="详细信息"
|
||||
)
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'success',
|
||||
'message': '确认通知已发送',
|
||||
'sticky': False,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
def all_put(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': '批量发送确认弹窗',
|
||||
'res_model': 'vacation.put.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
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):
|
||||
@@ -738,11 +695,11 @@ class YuthonVacationReports(models.Model):
|
||||
self._update_over_lines(new_report, [last_month_record], overtime_hours)
|
||||
|
||||
else:
|
||||
# 如果没有已确认的上月记录,创建空的本月报告
|
||||
self.create({
|
||||
'employee_id': employee.id,
|
||||
'vacation_date': current_month_first,
|
||||
})
|
||||
# 如果没有已确认的上月记录,创建空的本月报告
|
||||
self.create({
|
||||
'employee_id': employee.id,
|
||||
'vacation_date': current_month_first,
|
||||
})
|
||||
|
||||
|
||||
def _update_leave_lines(self, report, allocations, number_of_hours_display):
|
||||
|
||||
@@ -75,4 +75,7 @@ access_planning_slot_update_display_name_wizard,access_planning_slot_update_disp
|
||||
access_expatriation_approval,expatriation.approval,model_expatriation_approval,base.group_user,1,1,1,1
|
||||
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_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
|
||||
|
@@ -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"/>
|
||||
|
||||
@@ -5,4 +5,6 @@ from . import yuthon_delete_planning_wizard
|
||||
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 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
|
||||
|
||||
Reference in New Issue
Block a user