添加功能
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
'wizard/attendance_controls_wizard.xml',
|
||||
'wizard/attendance_correct_wizard.xml',
|
||||
'wizard/vacation_put_wizard_views.xml',
|
||||
'wizard/vacation_reports_wizard.xml',
|
||||
'wizard/vacation_confirm_wizard_views.xml',
|
||||
'wizard/planning_slot_update_display_name_wizard.xml',
|
||||
'wizard/yuthon_run_wizard.xml',
|
||||
|
||||
@@ -33,7 +33,7 @@ class YuthonVacationReports(models.Model):
|
||||
year_workday = fields.Float(string="本年工作日", digits=(16, 3))
|
||||
year_sum = fields.Float(string="本年应休合计", digits=(16, 3), compute="_compute_year_sum")
|
||||
used_this_year1 = fields.Float(string="本年已休", digits=(16, 3), compute="_compute_year_sum")
|
||||
remainder_year1 = fields.Float(string="本年剩余(补休)", digits=(16, 3))
|
||||
remainder_year1 = fields.Float(string="本年剩余(补休)", digits=(16, 3), compute="_compute_year_sum")
|
||||
|
||||
company_id = fields.Many2one(related="employee_id.company_id", string="公司", store=True)
|
||||
late_allowed = fields.Float(related="employee_id.late_allowed", string="允许迟到次数")
|
||||
@@ -133,7 +133,6 @@ class YuthonVacationReports(models.Model):
|
||||
record.year_sum = record.last_holiday + record.last_workday + record.year_holiday + record.year_workday
|
||||
record.remainder_year1 = record.year_sum - record.used_this_year1
|
||||
|
||||
|
||||
@api.constrains('employee_id', 'vacation_date')
|
||||
def _check_duplicate_monthly_record(self):
|
||||
"""检查是否存在同一员工当月的重复记录"""
|
||||
@@ -176,6 +175,38 @@ class YuthonVacationReports(models.Model):
|
||||
|
||||
def confirm_state(self):
|
||||
for rec in self:
|
||||
current_user = self.env.user
|
||||
is_admin = current_user.has_group('base.group_system') or current_user.has_group('base.group_admin')
|
||||
if not is_admin:
|
||||
if rec.vacation_date.month == 1:
|
||||
last_month_year = rec.vacation_date.year - 1
|
||||
last_month = 12
|
||||
else:
|
||||
last_month_year = rec.vacation_date.year
|
||||
last_month = rec.vacation_date.month - 1
|
||||
last_day_of_last_month = calendar.monthrange(last_month_year, last_month)[1]
|
||||
last_month_start = fields.Date.from_string(f'{last_month_year}-{last_month:02d}-01')
|
||||
last_month_end = fields.Date.from_string(f'{last_month_year}-{last_month:02d}-{last_day_of_last_month}')
|
||||
leave_batch_domain = [
|
||||
('users_id', '=', current_user.id),
|
||||
('start_date', '>=', last_month_start),
|
||||
('end_date', '<=', last_month_end),
|
||||
('work_end', '!=', True)
|
||||
]
|
||||
invalid_leave_batches = self.env['hr.leave.batch'].search(leave_batch_domain)
|
||||
if invalid_leave_batches:
|
||||
raise UserError('有假单未结束, 请先结束假期批次')
|
||||
current_employee_id = self.env['hr.employee'].search([('user_id', '=', current_user.id)], limit=1).id
|
||||
overtime_domain = [
|
||||
('employee_ids', 'in', current_employee_id),
|
||||
('start_time', '>=', last_month_start),
|
||||
('start_time', '<=', last_month_end),
|
||||
('work_end', '!=', True)
|
||||
]
|
||||
invalid_overtimes = self.env['overtime.approval'].search(overtime_domain)
|
||||
if invalid_overtimes:
|
||||
raise UserError('有加班单未结束,请先结束加班批次')
|
||||
|
||||
rec.manage_reject()
|
||||
|
||||
@api.depends('vacation_date')
|
||||
@@ -292,22 +323,44 @@ class YuthonVacationReports(models.Model):
|
||||
records = self.env["yuthon.vacation.reports"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id', self.ids))
|
||||
)
|
||||
for record in records:
|
||||
last_month_last = record.vacation_date - timedelta(days=1)
|
||||
last_month_first = last_month_last.replace(day=1)
|
||||
last_month_record = self.search([
|
||||
('employee_id', '=', record.employee_id.id),
|
||||
('vacation_date', '>=', fields.Date.to_string(last_month_first)),
|
||||
('vacation_date', '<=', fields.Date.to_string(last_month_last)),
|
||||
('vacation_state', '=', 'confirmed')
|
||||
], limit=1)
|
||||
inherit_vals = {
|
||||
'previous_year': last_month_record.remainder_year,
|
||||
'last_workday': last_month_record.remainder_year1,
|
||||
'remainder_year': 0.0,
|
||||
'remainder_year1': 0.0,
|
||||
}
|
||||
record.write(inherit_vals)
|
||||
for rec in records:
|
||||
leave_line_domain = [
|
||||
('vacation_id', '=', rec.id),
|
||||
('text', '=', "上月额度继承"),
|
||||
('employee_id', '=', rec.employee_id.id)
|
||||
]
|
||||
existing_leave_line = self.env['vacation.leave.line'].search(leave_line_domain, limit=1)
|
||||
if existing_leave_line:
|
||||
existing_leave_line.unlink()
|
||||
if rec.year_distribution:
|
||||
self.env['vacation.leave.line'].create({
|
||||
'vacation_id': rec.id,
|
||||
'employee_id': rec.employee_id.id,
|
||||
'update_type': 'add',
|
||||
'update_date': fields.Date.today(),
|
||||
'update_lines': rec.year_distribution * 8,
|
||||
'is_void': False,
|
||||
'allocation_type': 'allocation',
|
||||
'text': "上月额度继承"
|
||||
})
|
||||
over_line_domain = [
|
||||
('vacation_id', '=', rec.id),
|
||||
('employee_id', '=', rec.employee_id.id)
|
||||
]
|
||||
existing_over_lines = self.env['vacation.over.line'].search(over_line_domain)
|
||||
if existing_over_lines:
|
||||
existing_over_lines.unlink()
|
||||
if rec.year_holiday or rec.year_workday:
|
||||
over_line_create_vals = {
|
||||
'vacation_id': rec.id,
|
||||
'employee_id': rec.employee_id.id,
|
||||
'update_type': 'add',
|
||||
'workday': rec.year_workday * 8,
|
||||
'public_holidays': rec.year_holiday * 8,
|
||||
'legal_day': 0.0,
|
||||
'text': "上月额度继承"
|
||||
}
|
||||
self.env['vacation.over.line'].create(over_line_create_vals)
|
||||
|
||||
def _compute_attendance_fields1(self):
|
||||
records = self.env["yuthon.vacation.reports"].browse(
|
||||
@@ -320,11 +373,13 @@ class YuthonVacationReports(models.Model):
|
||||
})
|
||||
|
||||
def update_data(self):
|
||||
records = self.env["yuthon.vacation.reports"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id', self.ids))
|
||||
)
|
||||
for rec in records:
|
||||
rec._compute_working_overtime()
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"name": "导入",
|
||||
"res_model": "vacation.reports.wizard",
|
||||
"view_mode": "form",
|
||||
"target": "new",
|
||||
}
|
||||
|
||||
@api.depends('other_fee_ids', 'other_fee_ids.holiday_type', 'other_fee_ids.lines',
|
||||
'other_fee_ids.is_void', 'other_fee_ids.update_type')
|
||||
@@ -466,38 +521,6 @@ class YuthonVacationReports(models.Model):
|
||||
:return:
|
||||
'''
|
||||
for rec in self:
|
||||
current_user = self.env.user
|
||||
is_admin = current_user.has_group('base.group_system') or current_user.has_group('base.group_admin')
|
||||
if not is_admin:
|
||||
if rec.vacation_date.month == 1:
|
||||
last_month_year = rec.vacation_date.year - 1
|
||||
last_month = 12
|
||||
else:
|
||||
last_month_year = rec.vacation_date.year
|
||||
last_month = rec.vacation_date.month - 1
|
||||
last_day_of_last_month = calendar.monthrange(last_month_year, last_month)[1]
|
||||
last_month_start = fields.Date.from_string(f'{last_month_year}-{last_month:02d}-01')
|
||||
last_month_end = fields.Date.from_string(f'{last_month_year}-{last_month:02d}-{last_day_of_last_month}')
|
||||
leave_batch_domain = [
|
||||
('users_id', '=', current_user.id),
|
||||
('start_date', '>=', last_month_start),
|
||||
('end_date', '<=', last_month_end),
|
||||
('work_end', '!=', True)
|
||||
]
|
||||
invalid_leave_batches = self.env['hr.leave.batch'].search(leave_batch_domain)
|
||||
if invalid_leave_batches:
|
||||
raise UserError('有假单未结束, 请先结束假期批次')
|
||||
current_employee_id = self.env['hr.employee'].search([('user_id', '=', current_user.id)], limit=1).id
|
||||
overtime_domain = [
|
||||
('employee_ids', 'in', current_employee_id),
|
||||
('start_time', '>=', last_month_start),
|
||||
('start_time', '<=', last_month_end),
|
||||
('work_end', '!=', True)
|
||||
]
|
||||
invalid_overtimes = self.env['overtime.approval'] .search(overtime_domain)
|
||||
if invalid_overtimes:
|
||||
raise UserError('有加班单未结束,请先结束加班批次')
|
||||
|
||||
last_month_last = rec.vacation_date - timedelta(days=1)
|
||||
last_month_first = last_month_last.replace(day=1)
|
||||
last_month_record = self.search([
|
||||
@@ -512,15 +535,12 @@ class YuthonVacationReports(models.Model):
|
||||
last_month_year = last_month_last.year
|
||||
is_cross_year = current_year != last_month_year
|
||||
if is_cross_year:
|
||||
last_month_record.write({
|
||||
'remainder_year': last_month_record.leave,
|
||||
'remainder_year1': last_month_record.working_overtime,
|
||||
})
|
||||
inherit_vals = {
|
||||
'previous_year': last_month_record.remainder_year,
|
||||
'last_workday': last_month_record.remainder_year1,
|
||||
'remainder_year': 0.0,
|
||||
'remainder_year1': 0.0,
|
||||
'last_workday': last_month_record.year_workday,
|
||||
'last_holiday': last_month_record.year_holiday,
|
||||
'year_holiday': 0.0,
|
||||
'year_workday': 0.0,
|
||||
}
|
||||
rec.write(inherit_vals)
|
||||
|
||||
|
||||
@@ -80,4 +80,6 @@ access_staff_dining_report,staff.dining.report,model_staff_dining_report,base.gr
|
||||
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
|
||||
access_message_reminder_tasks,message.reminder.tasks,model_message_reminder_tasks,base.group_user,1,1,1,1
|
||||
access_applet_security_quick_perm_wizard,access_applet_security_quick_perm_wizard,model_applet_security_quick_perm_wizard,base.group_user,1,1,1,1
|
||||
access_applet_security_quick_perm_wizard,access_applet_security_quick_perm_wizard,model_applet_security_quick_perm_wizard,base.group_user,1,1,1,1
|
||||
|
||||
access_vacation_reports_wizard,vacation.reports.wizard,model_vacation_reports_wizard,base.group_user,1,1,1,1
|
||||
|
@@ -9,3 +9,4 @@ from . import planning_slot_update_display_name_wizard
|
||||
from . import vacation_confirm_wizard
|
||||
from . import vacation_put_wizard
|
||||
from . import applet_security_quick_perm_wizard
|
||||
from . import vacation_reports_wizard
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _, SUPERUSER_ID
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from pypinyin import pinyin, Style
|
||||
import xlrd
|
||||
import base64
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class VacationReportsWizard(models.TransientModel):
|
||||
_name = 'vacation.reports.wizard'
|
||||
_description = '考勤报表导入'
|
||||
|
||||
excel_file = fields.Binary(string="上传Excel表")
|
||||
excel_name = fields.Char(string="文件名")
|
||||
report_ids = fields.Many2many('yuthon.vacation.reports', string='报表')
|
||||
|
||||
def confirm(self):
|
||||
"""
|
||||
导入excel文件,按行读取数据并处理
|
||||
:return: 导入员工信息表并更新
|
||||
"""
|
||||
if not self.excel_file:
|
||||
raise ValidationError('请上传文件。')
|
||||
book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
|
||||
sh = book.sheet_by_index(0)
|
||||
for rx in range(1, sh.nrows):
|
||||
row = sh.row(rx)
|
||||
self.leave_import(row)
|
||||
|
||||
def leave_import(self, row):
|
||||
employee_id = self.env['hr.employee'].search([('name', '=', row[0].value)])
|
||||
year_distribution = row[1].value
|
||||
start_date = fields.Date.from_string("2025-12-1")
|
||||
report_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', employee_id.id),
|
||||
('vacation_date', '=', start_date)
|
||||
])
|
||||
if report_id:
|
||||
report_id.write({'year_distribution': year_distribution})
|
||||
|
||||
|
||||
def over_import(self, row):
|
||||
employee_id = self.env['hr.employee'].search([('name', '=', row[0].value)])
|
||||
year_holiday = float(row[12].value)
|
||||
year_workday = float(row[11].value)
|
||||
if not year_workday and not year_holiday:
|
||||
year_workday = float(row[10].value)
|
||||
start_date = fields.Date.from_string("2025-12-1")
|
||||
report_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', employee_id.id),
|
||||
('vacation_date', '=', start_date)
|
||||
])
|
||||
if report_id:
|
||||
report_id.write(
|
||||
{'year_holiday': year_holiday / 8
|
||||
,'year_workday': year_workday / 8
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="vacation_reports_wizard_form" model="ir.ui.view">
|
||||
<field name="name">导入</field>
|
||||
<field name="model">vacation.reports.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="excel_file" filename="excel_name"/>
|
||||
<field name="excel_name" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button name="confirm" string="确认" type="object" class="oe_highlight"/>
|
||||
<button string="返回" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user