diff --git a/yuthon_hr_attendance/wizard/__init__.py b/yuthon_hr_attendance/wizard/__init__.py index 8000428ca..89d35de8a 100644 --- a/yuthon_hr_attendance/wizard/__init__.py +++ b/yuthon_hr_attendance/wizard/__init__.py @@ -10,4 +10,4 @@ from . import vacation_confirm_wizard from . import planning_slot_update_display_name_wizard from . import yuthon_run_wizard from . import applet_security_quick_perm_wizard -# from . import export_date_wizard +from . import export_date_wizard diff --git a/yuthon_hr_attendance/wizard/export_date_wizard.py b/yuthon_hr_attendance/wizard/export_date_wizard.py new file mode 100644 index 000000000..db7a48acb --- /dev/null +++ b/yuthon_hr_attendance/wizard/export_date_wizard.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models +import json +from odoo.tools import date_utils +from datetime import datetime +from odoo.exceptions import UserError + + +class ExportDateWizard(models.TransientModel): + _name = 'export.date.wizard' + _description = '导出日期选择向导' + + year = fields.Integer(string='年份', required=True, default=lambda self: datetime.now().year) + month = fields.Selection([ + ('1', '1月'), ('2', '2月'), ('3', '3月'), ('4', '4月'), + ('5', '5月'), ('6', '6月'), ('7', '7月'), ('8', '8月'), + ('9', '9月'), ('10', '10月'), ('11', '11月'), ('12', '12月'), + ], string='月份', required=True, default=lambda self: str(datetime.now().month)) + + export_type = fields.Char(string='导出类型') + model_name = fields.Char(string='模型名称') + active_ids = fields.Char(string='活动记录ID') + + def action_confirm_export(self): + """确认导出""" + self.ensure_one() + + start_date = datetime(int(self.year), int(self.month), 1) + if int(self.month) == 12: + end_date = datetime(int(self.year) + 1, 1, 1) + else: + end_date = datetime(int(self.year), int(self.month) + 1, 1) + + if self.export_type == 'leave': + return self._export_leave(start_date, end_date) + elif self.export_type == 'leave_filing': + return self._export_leave_filing(start_date, end_date) + elif self.export_type == 'overtime': + return self._export_overtime(start_date, end_date) + elif self.export_type == 'overtime_detail': + return self._export_overtime_detail(start_date, end_date) + elif self.export_type == 'overtime_active': + return self._export_overtime_active(start_date, end_date) + elif self.export_type == 'meal': + return self._export_meal(start_date, end_date) + else: + raise UserError('未知的导出类型') + + def _export_leave(self, start_date, end_date): + """导出请假情况""" + active_ids = json.loads(self.active_ids) if self.active_ids else [] + + domain = [('date_from', '>=', start_date), ('date_from', '<', end_date)] + if active_ids: + domain = [('id', 'in', active_ids)] + domain + + filtered_records = self.env['hr.leave'].search(domain) + + if not filtered_records: + raise UserError(f'在 {self.year} 年 {self.month} 月没有找到符合条件的请假记录') + + filtered_ids = filtered_records.ids + + fields_name = ['employee_id', 'department_id', 'holiday_status_id', 'caption', + 'date_from', 'date_to', 'length_leave', 'application_reason', 'mobile_phone'] + field_label = ['发起人', '部门', '休假类型', '标题', '开始时间', '结束时间', + '请假时长', '申请原因', '手机号'] + + data = { + 'report_name': '请假情况报表', + 'model_name': 'hr.leave', + 'fields_name': fields_name, + 'field_label': field_label, + 'active_ids': filtered_ids, + } + + return { + 'type': 'ir.actions.report', + 'data': { + 'model': 'report.excel', + 'options': json.dumps(data, default=date_utils.json_default), + 'output_format': 'xlsx', + 'report_name': '请假情况报表', + }, + 'report_type': 'xlsx', + } + + def _export_leave_filing(self, start_date, end_date): + """导出归档请假情况(is_filiing=True)""" + active_ids = json.loads(self.active_ids) if self.active_ids else [] + + domain = [ + ('date_from', '>=', start_date), + ('date_from', '<', end_date), + ('is_filiing', '=', True) + ] + if active_ids: + domain = [('id', 'in', active_ids)] + domain + + filtered_records = self.env['hr.leave'].search(domain) + + if not filtered_records: + raise UserError(f'在 {self.year} 年 {self.month} 月没有找到符合条件的归档请假记录(is_filiing=True)') + + filtered_ids = filtered_records.ids + + fields_name = ['employee_id', 'department_id', 'holiday_status_id', 'caption', + 'date_from', 'date_to', 'length_leave', 'application_reason', 'mobile_phone'] + field_label = ['发起人', '部门', '休假类型', '标题', '开始时间', '结束时间', + '请假时长', '申请原因', '手机号'] + + data = { + 'report_name': '归档请假情况报表', + 'model_name': 'hr.leave', + 'fields_name': fields_name, + 'field_label': field_label, + 'active_ids': filtered_ids, + } + + return { + 'type': 'ir.actions.report', + 'data': { + 'model': 'report.excel', + 'options': json.dumps(data, default=date_utils.json_default), + 'output_format': 'xlsx', + 'report_name': '归档请假情况报表', + }, + 'report_type': 'xlsx', + } + + def _export_overtime(self, start_date, end_date): + """导出加班明细""" + active_ids = json.loads(self.active_ids) if self.active_ids else [] + + domain = [('start_time', '>=', start_date), ('start_time', '<', end_date)] + if active_ids: + domain = [('id', 'in', active_ids)] + domain + + filtered_records = self.env['vacation.over.line'].search(domain) + + if not filtered_records: + raise UserError(f'在 {self.year} 年 {self.month} 月没有找到符合条件的加班记录') + + filtered_ids = filtered_records.ids + + fields_name = ['employee_id', 'department_id', 'start_time', 'carry_forward_date', + 'duration', 'carry_result'] + field_label = ['员工', '部门', '加班时间', '结转日期', '结转时长', '结转结果'] + + data = { + 'report_name': '加班明细报表', + 'model_name': 'vacation.over.line', + 'fields_name': fields_name, + 'field_label': field_label, + 'active_ids': filtered_ids, + } + + return { + 'type': 'ir.actions.report', + 'data': { + 'model': 'report.excel', + 'options': json.dumps(data, default=date_utils.json_default), + 'output_format': 'xlsx', + 'report_name': '加班明细报表', + }, + 'report_type': 'xlsx', + } + + def _export_overtime_detail(self, start_date, end_date): + """导出加班详情""" + active_ids = json.loads(self.active_ids) if self.active_ids else [] + + domain = [('start_time', '>=', start_date), ('start_time', '<', end_date)] + if active_ids: + domain = [('id', 'in', active_ids)] + domain + + filtered_records = self.env['vacation.over.line'].search(domain) + + if not filtered_records: + raise UserError(f'在 {self.year} 年 {self.month} 月没有找到符合条件的加班记录') + + filtered_ids = filtered_records.ids + + fields_name = ['employee_id', 'department_id', 'workflow_id', 'start_time', + 'end_time', 'duration', 'reason_application', 'meal'] + field_label = ['员工', '部门', '审批类型', '加班开始时间', '加班结束时间', + '加班时长', '事由', '加班餐费'] + + data = { + 'report_name': '加班详情报表', + 'model_name': 'vacation.over.line', + 'fields_name': fields_name, + 'field_label': field_label, + 'active_ids': filtered_ids, + } + + return { + 'type': 'ir.actions.report', + 'data': { + 'model': 'report.excel', + 'options': json.dumps(data, default=date_utils.json_default), + 'output_format': 'xlsx', + 'report_name': '加班详情报表', + }, + 'report_type': 'xlsx', + } + + def _export_overtime_active(self, start_date, end_date): + """导出加班归档明细""" + active_ids = json.loads(self.active_ids) if self.active_ids else [] + + domain = [('start_time', '>=', start_date), ('start_time', '<', end_date)] + if active_ids: + domain = [('id', 'in', active_ids)] + domain + + filtered_records = self.env['overtime.active.line'].search(domain) + + if not filtered_records: + raise UserError(f'在 {self.year} 年 {self.month} 月没有找到符合条件的加班归档记录') + + filtered_ids = filtered_records.ids + + fields_name = ['employee_id', 'department_id', 'start_time', 'end_time', + 'carry_forward_date', 'carry_forward_quantity', 'carry_forward_state'] + field_label = ['姓名', '部门', '加班开始时间', '加班结束时间', '结转日期', + '结转时长', '结转结果'] + + data = { + 'report_name': '加班归档明细报表', + 'model_name': 'overtime.active.line', + 'fields_name': fields_name, + 'field_label': field_label, + 'active_ids': filtered_ids, + } + + return { + 'type': 'ir.actions.report', + 'data': { + 'model': 'report.excel', + 'options': json.dumps(data, default=date_utils.json_default), + 'output_format': 'xlsx', + 'report_name': '加班归档明细报表', + }, + 'report_type': 'xlsx', + } + + def _export_meal(self, start_date, end_date): + """导出误餐明细""" + active_ids = json.loads(self.active_ids) if self.active_ids else [] + + domain = [('start_time', '>=', start_date), ('start_time', '<', end_date)] + if active_ids: + domain = [('id', 'in', active_ids)] + domain + + filtered_records = self.env['vacation.meal.line'].search(domain) + + if not filtered_records: + raise UserError(f'在 {self.year} 年 {self.month} 月没有找到符合条件的误餐记录') + + filtered_ids = filtered_records.ids + + fields_name = ['employee_id', 'department_id', 'workflow_id', 'start_time', + 'end_time', 'duration', 'reasons', 'meal'] + field_label = ['发起人', '部门', '审批类型', '加班开始时间', '加班结束时间', + '加班时长', '事由', '加班餐费'] + + data = { + 'report_name': '误餐明细报表', + 'model_name': 'vacation.meal.line', + 'fields_name': fields_name, + 'field_label': field_label, + 'active_ids': filtered_ids, + } + + return { + 'type': 'ir.actions.report', + 'data': { + 'model': 'report.excel', + 'options': json.dumps(data, default=date_utils.json_default), + 'output_format': 'xlsx', + 'report_name': '误餐明细报表', + }, + 'report_type': 'xlsx', + } diff --git a/yuthon_hr_attendance/wizard/export_date_wizard_views.xml b/yuthon_hr_attendance/wizard/export_date_wizard_views.xml new file mode 100644 index 000000000..1a7ccef00 --- /dev/null +++ b/yuthon_hr_attendance/wizard/export_date_wizard_views.xml @@ -0,0 +1,22 @@ + + + + export.date.wizard.form + export.date.wizard + +
+ + + + + + + + +
+
+
+