@@ -69,6 +69,7 @@
|
||||
'views/yuthon_holiday_statement.xml',
|
||||
'views/yuthon_parenting_allocate_views.xml',
|
||||
'views/all_attendance_menu.xml',
|
||||
'views/overtime_active_line_views.xml',
|
||||
'views/overtime_approval_inherit_header.xml',
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ from . import yuthon_meal_case
|
||||
from . import yuthon_parenting_allocate
|
||||
from . import vacation_overtime_active
|
||||
from . import yuthon_overtime_line
|
||||
from . import overtime_active_line
|
||||
# from odoo.tools import SQL
|
||||
# import odoo
|
||||
# odoo.models.READ_GROUP_AGGREGATE.update({
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class OvertimeActiveLine(models.Model):
|
||||
_name = 'overtime.active.line'
|
||||
_description = '加班归档详情'
|
||||
|
||||
overtime_name = fields.Char(string='标题')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工')
|
||||
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one('res.company', related='employee_id.company_id', string="公司")
|
||||
start_time = fields.Datetime(string="开始时间")
|
||||
end_time = fields.Datetime(string="结束时间")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
duration = fields.Float(string="时长")
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
carry_forward_state = fields.Selection([('pending', '待结转'), ('completed', '已结转'), ('partial', '部分结转')
|
||||
], string='结转状态',
|
||||
default='pending',
|
||||
)
|
||||
remaining_quantity = fields.Float(string='剩余数')
|
||||
validity = fields.Char(string="有效期")
|
||||
is_void = fields.Boolean(string="作废", default=False)
|
||||
@@ -29,13 +29,17 @@ class VacationOvertimeActive(models.Model):
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
remaining_quantity = fields.Float(string="剩余数")
|
||||
select_revoke = fields.Selection([('to_do', '待撤销'), ('done', '已撤销')], string='状态')
|
||||
|
||||
def open_record(self):
|
||||
def revoke(self):
|
||||
self.ensure_one()
|
||||
self.select_revoke = 'done'
|
||||
current_year = int(self.select_year)
|
||||
current_month = int(self.select_month)
|
||||
cutoff_date = date(current_year, current_month, 1) - timedelta(days=1)
|
||||
cutoff_dt = datetime.combine(cutoff_date, datetime.min.time())
|
||||
next_month = current_month + 1 if current_month < 12 else 1
|
||||
next_year = current_year if current_month < 12 else current_year + 1
|
||||
cutoff_date_last = date(next_year, next_month, 1) - timedelta(days=1)
|
||||
cutoff_dt = datetime.combine(cutoff_date_last, datetime.max.time())
|
||||
dec_2025_end = datetime(2025, 12, 31, 23, 59, 59)
|
||||
domain = [
|
||||
('start_time', '<', cutoff_dt),
|
||||
@@ -45,9 +49,7 @@ class VacationOvertimeActive(models.Model):
|
||||
if self.employee_id.company_id.name == '集团本部':
|
||||
domain = [
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
'|',
|
||||
('carry_forward_date', '=', False),
|
||||
('carry_forward_date', '<', cutoff_dt),
|
||||
('carry_forward_date', '!=', False),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
@@ -57,14 +59,55 @@ class VacationOvertimeActive(models.Model):
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<', cutoff_dt)
|
||||
]
|
||||
over_ids = self.env['vacation.over.line'].search(domain)
|
||||
if over_ids:
|
||||
for over_id in over_ids:
|
||||
over_id.carry_forward_quantity = 0
|
||||
over_id.carry_forward_state = 'pending'
|
||||
over_id.carry_forward_date = False
|
||||
|
||||
tree_id = self.env.ref("yuthon_hr_attendance.view_yuthon_vacation_overtime_tree").id
|
||||
domain1 = [
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('carry_forward_date', '=', self.carry_forward_date)
|
||||
]
|
||||
active_line_ids = self.env['overtime.active.line'].search(domain1)
|
||||
if active_line_ids:
|
||||
for active_line_id in active_line_ids:
|
||||
active_line_id.is_void = True
|
||||
|
||||
report_id = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('vacation_date', '=', self.carry_forward_date.replace(day=1))
|
||||
], limit=1)
|
||||
reduce_over_lines = self.env['vacation.over.line'].search([
|
||||
('vacation_id', '=', report_id.id),
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('update_type', '=', 'reduce'),
|
||||
('workday', '=', self.carry_forward_quantity),
|
||||
])
|
||||
if reduce_over_lines:
|
||||
reduce_over_lines.unlink()
|
||||
report_id.update_line()
|
||||
|
||||
def all_revoke(self):
|
||||
overtime_ids = self.env["vacation.overtime.active"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for overtime_id in overtime_ids:
|
||||
if overtime_id.select_revoke == 'done':
|
||||
raise UserError(f"{overtime_id.employee_id}{overtime_id.select_month}已撤销,不能重复撤销")
|
||||
overtime_id.revoke()
|
||||
|
||||
def open_record(self):
|
||||
self.ensure_one()
|
||||
domain = [
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('carry_forward_date', '=', self.carry_forward_date)
|
||||
]
|
||||
return {
|
||||
'views': [[tree_id, 'tree']],
|
||||
'name': f'加班明细',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'vacation.over.line',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'overtime.active.line',
|
||||
'view_mode': 'tree',
|
||||
'domain': domain,
|
||||
'target': 'current'
|
||||
}
|
||||
|
||||
@@ -25,20 +25,21 @@ class YuthonOvertimeLine(models.Model):
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
archive_state = fields.Selection([('to_do', '待归档'), ('done', '已归档')], default='to_do', string='状态')
|
||||
remaining_quantity = fields.Float(string="剩余数", compute='_compute_vacation_sum', store=True)
|
||||
remaining_quantity = fields.Float(string="剩余数")
|
||||
|
||||
@api.depends('workday', 'public_holidays', 'carry_forward_quantity')
|
||||
def _compute_vacation_sum(self):
|
||||
for rec in self:
|
||||
rec.vacation_sum = rec.public_holidays + rec.workday
|
||||
rec.remaining_quantity = rec.vacation_sum - rec.carry_forward_quantity
|
||||
rec.vacation_sum = rec.public_holidays + rec.workday + rec.last_balance
|
||||
|
||||
def open_record(self):
|
||||
self.ensure_one()
|
||||
current_year = int(self.select_year)
|
||||
current_month = int(self.select_month)
|
||||
cutoff_date = date(current_year, current_month, 1) - timedelta(days=1)
|
||||
cutoff_dt = datetime.combine(cutoff_date, datetime.min.time())
|
||||
next_month = current_month + 1 if current_month < 12 else 1
|
||||
next_year = current_year if current_month < 12 else current_year + 1
|
||||
cutoff_date_last = date(next_year, next_month, 1) - timedelta(days=1)
|
||||
cutoff_dt = datetime.combine(cutoff_date_last, datetime.max.time())
|
||||
dec_2025_end = datetime(2025, 12, 31, 23, 59, 59)
|
||||
domain = [
|
||||
('start_time', '<', cutoff_dt),
|
||||
@@ -48,9 +49,7 @@ class YuthonOvertimeLine(models.Model):
|
||||
if self.employee_id.company_id.name == '集团本部':
|
||||
domain = [
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
'|',
|
||||
('carry_forward_date', '=', False),
|
||||
('carry_forward_date', '<', cutoff_dt),
|
||||
('carry_forward_state', '!=', 'completed'),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
@@ -128,50 +127,62 @@ class YuthonOvertimeLine(models.Model):
|
||||
continue # 该记录已无剩余可分配时长
|
||||
|
||||
if rec.is_initial_number and rec.last_balance > 1e-6:
|
||||
need_deduct_total = min(remaining_to_allocate, rec.last_balance)
|
||||
remaining_deduct = need_deduct_total
|
||||
if remaining_to_allocate >= max_allocation:
|
||||
# 足够分配完当前记录的剩余时长
|
||||
allocate_amount = max_allocation
|
||||
new_state = 'completed'
|
||||
remaining_to_allocate -= allocate_amount
|
||||
else:
|
||||
# 只能分配部分时长
|
||||
allocate_amount = remaining_to_allocate
|
||||
new_state = 'partial'
|
||||
remaining_to_allocate = 0
|
||||
|
||||
# 1. 优先扣减 vacation_id.last_workday
|
||||
if rec.vacation_id and rec.vacation_id.last_workday > 1e-6:
|
||||
deduct_workday = min(remaining_deduct, rec.vacation_id.last_workday)
|
||||
rec.vacation_id.last_workday -= deduct_workday
|
||||
remaining_deduct -= deduct_workday # 剩余待扣减金额减少
|
||||
rec.vacation_id.write({'last_workday': rec.vacation_id.last_workday})
|
||||
self.env['overtime.active.line'].create({
|
||||
'overtime_name': rec.overtime_name,
|
||||
'employee_id': rec.employee_id.id,
|
||||
'start_time': rec.start_time,
|
||||
'end_time': rec.end_time,
|
||||
'carry_forward_date': overtime_id.carry_forward_date,
|
||||
'duration': rec.duration,
|
||||
'carry_forward_quantity': allocate_amount,
|
||||
'carry_forward_state': new_state,
|
||||
'remaining_quantity': rec.remaining_quantity - allocate_amount,
|
||||
'validity': rec.validity if hasattr(rec, 'validity') else '',
|
||||
})
|
||||
|
||||
# 2.扣减 vacation_id.last_holiday
|
||||
if remaining_deduct > 1e-6 and rec.vacation_id and rec.vacation_id.last_holiday > 1e-6:
|
||||
deduct_holiday = min(remaining_deduct, rec.vacation_id.last_holiday)
|
||||
rec.vacation_id.last_holiday -= deduct_holiday
|
||||
remaining_deduct -= deduct_holiday
|
||||
rec.vacation_id.write({'last_holiday': rec.vacation_id.last_holiday})
|
||||
rec.write({
|
||||
'carry_forward_quantity': rec.carry_forward_quantity + allocate_amount,
|
||||
'carry_forward_state': new_state,
|
||||
'carry_forward_date': overtime_id.carry_forward_date
|
||||
})
|
||||
report_id = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', rec.employee_id.id),
|
||||
('vacation_date', '=', overtime_id.carry_forward_date.replace(day=1))
|
||||
], limit=1)
|
||||
if report_id:
|
||||
self.env['vacation.over.line'].create([{
|
||||
'vacation_id': report_id.id,
|
||||
'employee_id': rec.employee_id.id,
|
||||
'department_id': rec.department_id.id,
|
||||
'update_type': 'reduce',
|
||||
'workday': allocate_amount/8,
|
||||
'update_date': fields.Date.today(),
|
||||
'is_void': False,
|
||||
'overtime_methods': 'fee',
|
||||
'text': f'{overtime_id.carry_forward_date.month}月份加班结算',
|
||||
}])
|
||||
report_id.update_line()
|
||||
|
||||
# 确定本次分配的时长
|
||||
if remaining_to_allocate >= max_allocation:
|
||||
# 足够分配完当前记录的剩余时长
|
||||
allocate_amount = max_allocation
|
||||
new_state = 'completed'
|
||||
remaining_to_allocate -= allocate_amount
|
||||
else:
|
||||
# 只能分配部分时长
|
||||
allocate_amount = remaining_to_allocate
|
||||
new_state = 'partial'
|
||||
remaining_to_allocate = 0
|
||||
|
||||
rec.write({
|
||||
'carry_forward_quantity': rec.carry_forward_quantity + allocate_amount,
|
||||
'carry_forward_state': new_state,
|
||||
'carry_forward_date': overtime_id.carry_forward_date
|
||||
})
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'success',
|
||||
'message': '归档成功',
|
||||
'sticky': False,
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'success',
|
||||
'message': '归档成功',
|
||||
'sticky': False,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@api.model
|
||||
def carryover_details(self):
|
||||
@@ -181,7 +192,8 @@ class YuthonOvertimeLine(models.Model):
|
||||
overtime_lines = self.env['yuthon.overtime.line'].search(domain)
|
||||
for overtime in overtime_lines:
|
||||
overtime.carry_forward_date = fields.Date.today()
|
||||
overtime.carry_forward_quantity += overtime.remaining_quantity - 40
|
||||
overtime.carry_forward_quantity = overtime.vacation_sum - 40
|
||||
overtime.remaining_quantity = 40
|
||||
tree_id = self.env.ref("yuthon_hr_attendance.view_yuthon_overtime_line_tree1").id
|
||||
return {
|
||||
"name": _("结转明细"),
|
||||
|
||||
@@ -144,7 +144,7 @@ class YuthonVacationReports(models.Model):
|
||||
# ========== 第二步:处理补休逻辑 ==========
|
||||
for rec in self:
|
||||
reduce_overtime_lines = rec.overtime_ids.filtered(
|
||||
lambda o: o.workflow_record_id and o.update_type == 'reduce'
|
||||
lambda o: o.update_type == 'reduce' and (o.workflow_record_id or o.overtime_methods == 'fee')
|
||||
)
|
||||
# 计算补休扣减总天数
|
||||
total_overtime_deduct = sum(
|
||||
@@ -1336,36 +1336,43 @@ class YuthonVacationReports(models.Model):
|
||||
|
||||
@api.model
|
||||
def last_month(self):
|
||||
"""
|
||||
上月数据处理:
|
||||
- 2025年之前的记录:仅筛选is_initial_number = True
|
||||
- 2025年及之后的记录:按原有公司维度的复杂条件筛选
|
||||
"""
|
||||
base_line = self.env['yuthon.overtime.line'].search([], order='create_date asc', limit=1)
|
||||
if not base_line:
|
||||
return
|
||||
base_year = int(base_line.select_year)
|
||||
base_month = int(base_line.select_month)
|
||||
base_date = date(base_year, base_month, 1)
|
||||
self.env['yuthon.overtime.line'].search([]).unlink()
|
||||
current_date = base_date - timedelta(days=1)
|
||||
current_month_last = base_date - relativedelta(months=1) - timedelta(days=1)
|
||||
current_month_last_dt = datetime.combine(current_month_last, datetime.min.time())
|
||||
current_date = base_date - timedelta(days=1)
|
||||
dec_2025_end = datetime(2025, 12, 31, 23, 59, 59)
|
||||
if self.env.user.company_id.name == '集团本部':
|
||||
domain = [
|
||||
'|',
|
||||
('carry_forward_date', '=', False),
|
||||
('carry_forward_date', '<', current_month_last_dt),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
'&', ('update_type', '=', 'add'),
|
||||
'&', ('workflow_record_id', '!=', False),
|
||||
'&', ('start_time', '>=', dec_2025_end),
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<', current_month_last_dt)
|
||||
]
|
||||
is_before_2025 = current_date < date(2026, 1, 1)
|
||||
|
||||
if is_before_2025:
|
||||
domain = [('is_initial_number', '=', True)]
|
||||
else:
|
||||
domain = [
|
||||
('workflow_record_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('start_time', '<', current_month_last_dt)
|
||||
]
|
||||
if self.env.user.company_id.name == '集团本部':
|
||||
domain = [
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
'&', ('update_type', '=', 'add'),
|
||||
'&', ('workflow_record_id', '!=', False),
|
||||
'&', ('start_time', '>=', dec_2025_end),
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<=', current_date)
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
('workflow_record_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('start_time', '<', current_date)
|
||||
]
|
||||
all_records = self.env['vacation.over.line'].search(domain)
|
||||
over_lines = all_records.filtered(lambda r: abs(r.remaining_quantity) > 1e-6)
|
||||
if not over_lines:
|
||||
@@ -1380,25 +1387,37 @@ class YuthonVacationReports(models.Model):
|
||||
if emp_id not in employee_summary:
|
||||
employee_summary[emp_id] = {
|
||||
'employee_id': emp_id,
|
||||
'last_balance': line.last_balance,
|
||||
'valid_date': line.valid_date,
|
||||
'workday': 0.0,
|
||||
'public_holidays': 0.0,
|
||||
'carry_forward_quantity': 0.0,
|
||||
'carry_forward_date': line.carry_forward_date,
|
||||
'archive_state': 'done' if line.carry_forward_date else 'to_do',
|
||||
'remaining_quantity': 0.0,
|
||||
'select_month': str(current_date.month),
|
||||
'select_year': str(current_date.year)
|
||||
}
|
||||
|
||||
summary = employee_summary[emp_id]
|
||||
if line.is_initial_number:
|
||||
summary['workday'] += (line.workday or 0.0) - (line.last_balance or 0.0)
|
||||
else:
|
||||
summary['workday'] += line.workday or 0.0
|
||||
if line.workday:
|
||||
if line.is_initial_number:
|
||||
summary['last_balance'] = (line.remaining_quantity or 0.0)
|
||||
else:
|
||||
summary['workday'] += line.remaining_quantity or 0.0
|
||||
if line.public_holidays:
|
||||
summary['public_holidays'] += line.remaining_quantity or 0.0
|
||||
|
||||
if current_date.year == 2025:
|
||||
summary['last_balance'] = 0
|
||||
summary['workday'] = line.remaining_quantity
|
||||
summary['public_holidays'] = 0
|
||||
|
||||
summary['public_holidays'] += line.public_holidays or 0.0
|
||||
summary['carry_forward_quantity'] += line.carry_forward_quantity or 0.0
|
||||
summary['remaining_quantity'] = (
|
||||
summary.get('workday', 0.0) +
|
||||
summary.get('public_holidays', 0.0) +
|
||||
summary.get('last_balance', 0.0)
|
||||
)
|
||||
|
||||
create_vals = []
|
||||
for emp_id, vals in employee_summary.items():
|
||||
@@ -1414,14 +1433,9 @@ class YuthonVacationReports(models.Model):
|
||||
base_date = date(base_year, base_month, 1)
|
||||
self.env['yuthon.overtime.line'].search([]).unlink()
|
||||
current_date = (base_date + relativedelta(months=2)).replace(day=1) - timedelta(days=1)
|
||||
next_month_last = (base_date + relativedelta(months=1)).replace(day=1) - timedelta(days=1)
|
||||
next_month_last_dt = datetime.combine(next_month_last, datetime.min.time())
|
||||
dec_2025_end = datetime(2025, 12, 31, 23, 59, 59)
|
||||
if self.env.user.company_id.name == '集团本部':
|
||||
domain = [
|
||||
'|',
|
||||
('carry_forward_date', '=', False),
|
||||
('carry_forward_date', '<', next_month_last_dt),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
@@ -1429,14 +1443,14 @@ class YuthonVacationReports(models.Model):
|
||||
'&', ('workflow_record_id', '!=', False),
|
||||
'&', ('start_time', '>=', dec_2025_end),
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<', next_month_last_dt)
|
||||
('start_time', '<=', current_date)
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
('workflow_record_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('start_time', '<', next_month_last_dt)
|
||||
('start_time', '<=', current_date)
|
||||
]
|
||||
all_records = self.env['vacation.over.line'].search(domain)
|
||||
over_lines = all_records.filtered(lambda r: abs(r.remaining_quantity) > 1e-6)
|
||||
@@ -1451,25 +1465,34 @@ class YuthonVacationReports(models.Model):
|
||||
if emp_id not in employee_summary:
|
||||
employee_summary[emp_id] = {
|
||||
'employee_id': emp_id,
|
||||
'last_balance': line.last_balance,
|
||||
'valid_date': line.valid_date,
|
||||
'workday': 0.0,
|
||||
'public_holidays': 0.0,
|
||||
'carry_forward_quantity': 0.0,
|
||||
'carry_forward_date': line.carry_forward_date,
|
||||
'archive_state': 'done' if line.carry_forward_date else 'to_do',
|
||||
'select_month': str(current_date.month),
|
||||
'select_year': str(current_date.year)
|
||||
}
|
||||
|
||||
summary = employee_summary[emp_id]
|
||||
if line.is_initial_number:
|
||||
# 初始数据:workday = 本条workday - 本条last_balance
|
||||
summary['workday'] += (line.workday or 0.0) - (line.last_balance or 0.0)
|
||||
else:
|
||||
# 非初始数据:正常累加workday(原有逻辑)
|
||||
summary['workday'] += line.workday or 0.0
|
||||
if line.workday:
|
||||
if line.is_initial_number:
|
||||
summary['last_balance'] = (line.remaining_quantity or 0.0)
|
||||
else:
|
||||
summary['workday'] += line.remaining_quantity or 0.0
|
||||
if line.public_holidays:
|
||||
summary['public_holidays'] += line.remaining_quantity or 0.0
|
||||
|
||||
summary['public_holidays'] += line.public_holidays or 0.0
|
||||
if current_date.year == 2025:
|
||||
summary['last_balance'] = 0
|
||||
summary['workday'] = line.remaining_quantity
|
||||
summary['public_holidays'] = 0
|
||||
summary['remaining_quantity'] = (
|
||||
summary.get('workday', 0.0) +
|
||||
summary.get('public_holidays', 0.0) +
|
||||
summary.get('last_balance', 0.0)
|
||||
)
|
||||
summary['carry_forward_quantity'] += line.carry_forward_quantity or 0.0
|
||||
|
||||
create_vals = []
|
||||
@@ -1490,9 +1513,6 @@ class YuthonVacationReports(models.Model):
|
||||
# 原有domain(先筛选出基础数据)
|
||||
if self.env.user.company_id.name == '集团本部':
|
||||
domain = [
|
||||
'|',
|
||||
('carry_forward_date', '=', False),
|
||||
('carry_forward_date', '<', current_month_first_dt),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
@@ -1524,28 +1544,31 @@ class YuthonVacationReports(models.Model):
|
||||
if emp_id not in employee_summary:
|
||||
employee_summary[emp_id] = {
|
||||
'employee_id': emp_id,
|
||||
'last_balance': line.last_balance,
|
||||
'valid_date': line.valid_date,
|
||||
'workday': 0.0,
|
||||
'public_holidays': 0.0,
|
||||
'vacation_sum': 0.0,
|
||||
'carry_forward_quantity': 0.0,
|
||||
'carry_forward_date': line.carry_forward_date,
|
||||
'archive_state': 'done' if line.carry_forward_date else 'to_do',
|
||||
'select_month': str(last_month_first.month),
|
||||
'select_year': str(last_month_first.year)
|
||||
}
|
||||
|
||||
summary = employee_summary[emp_id]
|
||||
if line.is_initial_number:
|
||||
# 初始数据:workday = 本条workday - 本条last_balance
|
||||
summary['workday'] += (line.workday or 0.0) - (line.last_balance or 0.0)
|
||||
else:
|
||||
# 非初始数据:正常累加workday(原有逻辑)
|
||||
summary['workday'] += line.workday or 0.0
|
||||
|
||||
summary['public_holidays'] += line.public_holidays or 0.0
|
||||
if line.workday:
|
||||
if line.is_initial_number:
|
||||
summary['last_balance'] = (line.remaining_quantity or 0.0)
|
||||
else:
|
||||
summary['workday'] += line.remaining_quantity or 0.0
|
||||
if line.public_holidays:
|
||||
summary['public_holidays'] += line.remaining_quantity or 0.0
|
||||
summary['carry_forward_quantity'] += line.carry_forward_quantity or 0.0
|
||||
|
||||
summary['remaining_quantity'] = (
|
||||
summary.get('workday', 0.0) +
|
||||
summary.get('public_holidays', 0.0) +
|
||||
summary.get('last_balance', 0.0)
|
||||
)
|
||||
create_vals = []
|
||||
for emp_id, vals in employee_summary.items():
|
||||
create_vals.append(vals)
|
||||
@@ -1833,10 +1856,16 @@ class VacationMealLine(models.Model):
|
||||
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门", store=True)
|
||||
company_id = fields.Many2one('res.company', related='employee_id.company_id', string="公司", store=True)
|
||||
workflow_record_id = fields.Many2one('soong.workflow.record', string='流程')
|
||||
workflow_id = fields.Many2one(related="workflow_record_id.workflow_id", string="审批类型")
|
||||
vacation_date = fields.Date(related='vacation_id.vacation_date', string='误餐日期')
|
||||
update_type= fields.Selection([('add', '增加'), ('reduce', '减少')], string='更新类型')
|
||||
meal_name = fields.Char(string="标题", compute="_compute_overtime", store=True)
|
||||
start_date = fields.Date(string="日期", compute="_compute_overtime", store=True)
|
||||
start_time = fields.Float(string="开始时间", compute="_compute_overtime", store=True)
|
||||
end_time = fields.Float(string="结束时间", compute="_compute_overtime", store=True)
|
||||
duration = fields.Float(string="时长", compute="_compute_overtime", store=True)
|
||||
reasons = fields.Text(string="申请事由", compute="_compute_overtime", store=True)
|
||||
meal = fields.Selection([('yes', '是'), ('no', '否')], compute="_compute_overtime", default=None)
|
||||
update_date = fields.Date(string='更新时间')
|
||||
update_lines = fields.Float(string='更新额度')
|
||||
is_soon = fields.Boolean(string="流程修改")
|
||||
|
||||
@@ -90,4 +90,5 @@ access_vacation_parenting_line,vacation.parenting.line,model_vacation_parenting_
|
||||
access_yuthon_parenting_allocate,yuthon.parenting.allocate,model_yuthon_parenting_allocate,base.group_user,1,1,1,1
|
||||
access_vacation_overtime_active,vacation.overtime.active,model_vacation_overtime_active,base.group_user,1,1,1,1
|
||||
|
||||
access_yuthon_overtime_line,yuthon.overtime.line,model_yuthon_overtime_line,base.group_user,1,1,1,1
|
||||
access_yuthon_overtime_line,yuthon.overtime.line,model_yuthon_overtime_line,base.group_user,1,1,1,1
|
||||
access_overtime_active_line,overtime.active.line,model_overtime_active_line,base.group_user,1,1,1,1
|
||||
|
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="view_overtime_active_line_tree" model="ir.ui.view">
|
||||
<field name="name">overtime.active.line.tree</field>
|
||||
<field name="model">overtime.active.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班归档详情" editable="bottom" decoration-muted="is_void">
|
||||
<field name="overtime_name"/>
|
||||
<field name="employee_id" string="员工"/>
|
||||
<field name="department_id" string="部门"/>
|
||||
<field name="company_id" string="公司" column_invisible="1"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="duration"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_forward_state"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<field name="validity"/>
|
||||
<field name="is_void"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
<field name="model">vacation.overtime.active</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况(归档)" editable="bottom">
|
||||
<header>
|
||||
<button name="revoke" type="object" string="批量撤销" dclass="oe_highlight"/>
|
||||
</header>
|
||||
<field name="employee_id"/>
|
||||
<field name="select_year"/>
|
||||
<field name="select_month"/>
|
||||
<field name="select_year" column_invisible="1"/>
|
||||
<field name="select_month" column_invisible="1"/>
|
||||
<field name="last_balance"/>
|
||||
<field name="valid_date"/>
|
||||
<field name="workday"/>
|
||||
@@ -15,8 +18,10 @@
|
||||
<field name="vacation_sum" options='{ "fg_color": "red: vacation_sum > 40"}'/>
|
||||
<field name="carry_forward_quantity" options='{ "fg_color": "blue: carry_forward_quantity > 0"}'/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<field name="select_revoke" widget="badge"
|
||||
decoration-danger="select_revoke == 'done'" decoration-success="select_revoke == 'to_do'"/>
|
||||
<button name="open_record" type="object" string="详情" class="oe_highlight"/>
|
||||
<button name="revoke" type="object" string="撤销" class="oe_highlight" invisible="select_revoke == 'done'"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -24,7 +24,7 @@ class PayCarryoverWizard(models.TransientModel):
|
||||
for overtime in rec.overtime_ids:
|
||||
if overtime.text == '上月额度继承' and overtime.duration > 40:
|
||||
reduce_workday = overtime.workday - 40
|
||||
new_overtime = self.env['vacation.over.line'].create([{
|
||||
self.env['vacation.over.line'].create([{
|
||||
'vacation_id': rec.id,
|
||||
'employee_id': overtime.employee_id.id,
|
||||
'department_id': overtime.department_id.id,
|
||||
|
||||
Reference in New Issue
Block a user