@@ -10,14 +10,53 @@ class YuthonOvertimeLine(models.Model):
|
||||
_description = '加班明细'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string="员工")
|
||||
select_month = fields.Selection([('1', '一月'), ('2', '二月'), ('3', '三月'), ('4', '四月'),
|
||||
('5', '五月'), ('6', '六月'), ('7', '七月'), ('8', '八月'),
|
||||
('9', '九月'), ('10', '十月'), ('11', '十一月'),
|
||||
('12', '十二月')], string='月份',
|
||||
default=lambda self: str(datetime.now().month))
|
||||
select_year = fields.Selection(selection=[(str(i), str(i)) for i in range(2024, 2060)], string='年份',
|
||||
default=lambda self: str(datetime.now().year))
|
||||
last_balance = fields.Float(string="上年结余")
|
||||
valid_date = fields.Date(string="有效至")
|
||||
workday = fields.Float(string='工作日')
|
||||
public_holidays = fields.Float(string='公休日')
|
||||
vacation_sum = fields.Float(string='合计数')
|
||||
vacation_sum = fields.Float(string='合计数', compute='_compute_vacation_sum')
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
remaining_quantity = fields.Float(string="剩余数")
|
||||
remaining_quantity = fields.Float(string="剩余数", compute='_compute_vacation_sum')
|
||||
|
||||
@api.depends('workday', 'public_holidays', 'last_balance', 'carry_forward_quantity')
|
||||
def _compute_vacation_sum(self):
|
||||
for rec in self:
|
||||
rec.vacation_sum = rec.public_holidays + rec.workday + rec.last_balance
|
||||
rec.remaining_quantity = rec.vacation_sum - rec.carry_forward_quantity
|
||||
|
||||
def open_record(self):
|
||||
pass
|
||||
self.ensure_one()
|
||||
current_year = int(self.select_year)
|
||||
current_month = int(self.select_month)
|
||||
cutoff_date = date(current_year, current_month, 1)
|
||||
cutoff_dt = datetime.combine(cutoff_date, datetime.min.time())
|
||||
domain = [
|
||||
('start_time', '<', cutoff_dt),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('employee_id', '=', self.employee_id.id)
|
||||
]
|
||||
if current_year <= 2025 and self.employee_id.company_id.name == '集团本部':
|
||||
domain = [
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('is_initial_number', '=', True),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
]
|
||||
|
||||
tree_id = self.env.ref("yuthon_hr_attendance.view_yuthon_vacation_overtime_tree").id
|
||||
return {
|
||||
'views': [[tree_id, 'tree']],
|
||||
'name': f'加班明细',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'vacation.over.line',
|
||||
'view_mode': 'tree,form',
|
||||
'domain': domain,
|
||||
'target': 'current'
|
||||
}
|
||||
@@ -1006,6 +1006,246 @@ class YuthonVacationReports(models.Model):
|
||||
"view_mode": "form",
|
||||
}
|
||||
|
||||
@api.model
|
||||
def last_month(self):
|
||||
base_line = self.env['yuthon.overtime.line'].search([], order='create_date asc', limit=1)
|
||||
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()
|
||||
# 上上个月第一天(用于select_month赋值)
|
||||
last_month_first = (base_date - relativedelta(months=2)).replace(day=1)
|
||||
# 上上个月最后一天(时间筛选的截止点)
|
||||
current_month_last = (base_date - relativedelta(months=1)).replace(day=1) - timedelta(days=1)
|
||||
current_month_last_dt = datetime.combine(current_month_last, datetime.min.time())
|
||||
if self.env.user.company_id.name == '集团本部':
|
||||
domain = [
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
'&', ('update_type', '=', 'add'),
|
||||
'&', ('workflow_record_id', '!=', False),
|
||||
'&', ('start_time', '>=', '2025-12-01 00:00:00'),
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<', current_month_last_dt)
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
('workflow_record_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('start_time', '<', current_month_last_dt)
|
||||
]
|
||||
over_lines = self.env['vacation.over.line'].search(domain)
|
||||
if not over_lines:
|
||||
return
|
||||
|
||||
employee_summary = {}
|
||||
for line in over_lines:
|
||||
emp_id = line.employee_id.id
|
||||
if not emp_id:
|
||||
continue
|
||||
|
||||
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,
|
||||
'remaining_quantity': 0.0,
|
||||
'select_month': str(last_month_first.month),
|
||||
'select_year': str(last_month_first.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
|
||||
|
||||
summary['public_holidays'] += line.public_holidays or 0.0
|
||||
summary['carry_forward_quantity'] += line.carry_forward_quantity or 0.0
|
||||
|
||||
create_vals = []
|
||||
for emp_id, vals in employee_summary.items():
|
||||
create_vals.append(vals)
|
||||
if create_vals:
|
||||
self.env['yuthon.overtime.line'].create(create_vals)
|
||||
|
||||
@api.model
|
||||
def next_month(self):
|
||||
base_line = self.env['yuthon.overtime.line'].search([], order='create_date asc', limit=1)
|
||||
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()
|
||||
next_month_first = (base_date + relativedelta(months=1)).replace(day=1)
|
||||
next_month_last = (base_date + relativedelta(months=2)).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 = [
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
'&', ('update_type', '=', 'add'),
|
||||
'&', ('workflow_record_id', '!=', False),
|
||||
'&', ('start_time', '>=', '2025-12-01 00:00:00'),
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<', next_month_last_dt)
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
('workflow_record_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('start_time', '<', next_month_last_dt)
|
||||
]
|
||||
over_lines = self.env['vacation.over.line'].search(domain)
|
||||
if not over_lines:
|
||||
return
|
||||
|
||||
filtered_lines = []
|
||||
for line in over_lines:
|
||||
if not line.is_initial_number and line.start_time <= dec_2025_end:
|
||||
continue
|
||||
filtered_lines.append(line)
|
||||
|
||||
if not filtered_lines:
|
||||
return
|
||||
|
||||
employee_summary = {}
|
||||
for line in filtered_lines:
|
||||
emp_id = line.employee_id.id
|
||||
if not emp_id:
|
||||
continue
|
||||
|
||||
# 初始化员工汇总数据
|
||||
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,
|
||||
'select_month': str(next_month_first.month),
|
||||
'select_year': str(next_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
|
||||
summary['carry_forward_quantity'] += line.carry_forward_quantity or 0.0
|
||||
|
||||
create_vals = []
|
||||
for emp_id, vals in employee_summary.items():
|
||||
create_vals.append(vals)
|
||||
if create_vals:
|
||||
self.env['yuthon.overtime.line'].create(create_vals)
|
||||
|
||||
def overtime_line(self):
|
||||
self.env['yuthon.overtime.line'].search([]).unlink()
|
||||
today = date.today()
|
||||
last_month_first = (today - relativedelta(months=1)).replace(day=1)
|
||||
current_month_first = today.replace(day=1)
|
||||
current_month_first_dt = datetime.combine(current_month_first, datetime.min.time())
|
||||
dec_2025_end = datetime(2025, 12, 31, 23, 59, 59)
|
||||
|
||||
# 原有domain(先筛选出基础数据)
|
||||
if self.env.user.company_id.name == '集团本部':
|
||||
domain = [
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
'|',
|
||||
('is_initial_number', '=', True),
|
||||
'&', ('is_initial_number', '=', False),
|
||||
'&', ('update_type', '=', 'add'),
|
||||
'&', ('workflow_record_id', '!=', False),
|
||||
'&', ('start_time', '>=', '2025-12-01 00:00:00'),
|
||||
'&', ('vacation_id', '!=', False),
|
||||
('start_time', '<', current_month_first_dt)
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
('workflow_record_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('remaining_quantity', '!=', 0.0),
|
||||
('start_time', '<', current_month_first_dt)
|
||||
]
|
||||
|
||||
over_lines = self.env['vacation.over.line'].search(domain)
|
||||
if not over_lines:
|
||||
return
|
||||
|
||||
filtered_lines = []
|
||||
for line in over_lines:
|
||||
# 当前记录不是初始化记录 + start_time在2025-12月底前 → 跳过
|
||||
if not line.is_initial_number and line.start_time <= dec_2025_end:
|
||||
continue
|
||||
# 其他情况(初始化记录本身 / 无初始化记录 / 非初始化记录但时间在12月底后)→ 保留
|
||||
filtered_lines.append(line)
|
||||
|
||||
if not filtered_lines:
|
||||
return
|
||||
employee_summary = {}
|
||||
for line in filtered_lines:
|
||||
emp_id = line.employee_id.id
|
||||
if not emp_id:
|
||||
continue
|
||||
|
||||
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,
|
||||
'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
|
||||
summary['carry_forward_quantity'] += line.carry_forward_quantity or 0.0
|
||||
|
||||
create_vals = []
|
||||
for emp_id, vals in employee_summary.items():
|
||||
create_vals.append(vals)
|
||||
|
||||
if create_vals:
|
||||
self.env['yuthon.overtime.line'].create(create_vals)
|
||||
|
||||
return {
|
||||
"name": _("加班明细"),
|
||||
"type": "ir.actions.act_window",
|
||||
"view_mode": "tree",
|
||||
"res_model": "yuthon.overtime.line",
|
||||
"target": "current",
|
||||
}
|
||||
|
||||
|
||||
|
||||
class VacationLeaveLine(models.Model):
|
||||
_name = 'vacation.leave.line'
|
||||
|
||||
@@ -12,10 +12,10 @@ export class CustomAttendanceVacationConfirmController extends ListController {
|
||||
await this.orm.call('vacation.over.line', 'confirm', []);
|
||||
}
|
||||
async getNextAction(lock_type) {
|
||||
await this.orm.call('vacation.meal.line', 'confirm', []);
|
||||
await this.orm.call('yuthon.vacation.reports', 'next_month', []);
|
||||
}
|
||||
async getLastAction(lock_type) {
|
||||
await this.orm.call('vacation.meal.line', 'confirm', []);
|
||||
await this.orm.call('yuthon.vacation.reports', 'last_month', []);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,17 +39,10 @@ export class CustomAttendanceVacationPutController extends ListController {
|
||||
});
|
||||
}
|
||||
|
||||
openVacationOverWizard() {
|
||||
this.actionService.doAction({
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'yuthon.overtime.line',
|
||||
name: '加班合计数报表',
|
||||
view_mode: 'tree',
|
||||
view_type: 'form',
|
||||
views: [[false, 'tree']],
|
||||
target: 'current',
|
||||
context: {'tree_view_ref': "yuthon_hr_attendance.view_yuthon_overtime_line_tree"},
|
||||
});
|
||||
|
||||
|
||||
async getAction() {
|
||||
await this.orm.call('yuthon.vacation.reports', 'overtime_line', []);
|
||||
}
|
||||
|
||||
openYuthonVacationWizard() {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_list_buttons')]" position="after">
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openVacationOverWizard">
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="getAction">
|
||||
加班合计数报表
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班合计数报表" editable="bottom" js_class="custom_vacation_confirm_button" create="0">
|
||||
<field name="employee_id"/>
|
||||
<field name="select_year"/>
|
||||
<field name="select_month"/>
|
||||
<field name="last_balance"/>
|
||||
<field name="valid_date"/>
|
||||
<field name="workday"/>
|
||||
@@ -14,7 +16,7 @@
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<button name="open_record" type="object" string="结束" dclass="oe_highlight"/>
|
||||
<button name="open_record" type="object" string="详情" class="oe_highlight"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -659,7 +659,7 @@
|
||||
<field name="name">vacation.over.line.overtime.search</field>
|
||||
<field name="model">vacation.over.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="加班情况">
|
||||
<search string="加班明细">
|
||||
<field name="overtime_name"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="department_id"/>
|
||||
@@ -676,7 +676,7 @@
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_overtime_approval_report" model="ir.actions.act_window">
|
||||
<field name="name">加班情况</field>
|
||||
<field name="name">加班明细</field>
|
||||
<field name="res_model">vacation.over.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type',
|
||||
@@ -732,7 +732,7 @@
|
||||
<field name="res_model">yuthon.vacation.reports</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('is_filing','=', False)]</field>
|
||||
<field name="context">{'search_default_now_month': 1, 'search_default_group_by_employee_id':1}</field>
|
||||
<field name="context">{'search_default_now_month': 1}</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_yuthon_vacation_reports_tree')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_hr_attendance.view_yuthon_vacation_reports_form')})]"/>
|
||||
|
||||
Reference in New Issue
Block a user