添加功能
This commit is contained in:
@@ -70,6 +70,7 @@
|
||||
'views/yuthon_parenting_allocate_views.xml',
|
||||
'views/all_attendance_menu.xml',
|
||||
'views/overtime_active_line_views.xml',
|
||||
'views/vacation_meal_active_views.xml',
|
||||
'views/overtime_approval_inherit_header.xml',
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ from . import yuthon_parenting_allocate
|
||||
from . import vacation_overtime_active
|
||||
from . import yuthon_overtime_line
|
||||
from . import overtime_active_line
|
||||
from . import vacation_meal_active
|
||||
# from odoo.tools import SQL
|
||||
# import odoo
|
||||
# odoo.models.READ_GROUP_AGGREGATE.update({
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
from datetime import datetime, timedelta, time
|
||||
from email.policy import default
|
||||
from operator import index
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
import calendar
|
||||
from datetime import date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class VacationMealActive(models.Model):
|
||||
_name = 'vacation.meal.active'
|
||||
_description = '误餐费归档'
|
||||
|
||||
meal_name = fields.Char(string='标题')
|
||||
line_id = fields.Many2one('vacation.meal.line', string='关联误餐明细')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工')
|
||||
workflow_id = fields.Many2one('soong.workflow', string='审批类型')
|
||||
start_time = fields.Datetime(string='开始时间')
|
||||
end_time = fields.Datetime(string='结束时间')
|
||||
duration = fields.Float(string='时长')
|
||||
update_lines = fields.Float(string='额度')
|
||||
reasons = fields.Text(string='申请事由')
|
||||
meal = fields.Selection([('yes', '是'), ('no', '否')], string="误餐费", default=None)
|
||||
select_revoke = fields.Selection([('to_do', '待撤销'), ('done', '已撤销')], string='状态')
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
carry_forward_state = fields.Selection([('pending', '待结转'), ('completed', '已结转')
|
||||
], string='结转状态',
|
||||
default='pending',
|
||||
)
|
||||
|
||||
def revoke(self):
|
||||
self.ensure_one()
|
||||
self.select_revoke = 'done'
|
||||
self.line_id.is_filing = True
|
||||
report_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', self.employee_id.id),
|
||||
('vacation_date', '=', (self.start_time.date()).replace(day=1)),
|
||||
])
|
||||
meal_id = self.env['vacation.meal.line'].search([('vacation_id', '=', report_id.id),
|
||||
('update_type', '=', 'reduce')
|
||||
])
|
||||
if meal_id:
|
||||
meal_id.unlink()
|
||||
|
||||
def all_revoke(self):
|
||||
meal_ids = self.env["vacation.meal.active"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for meal_id in meal_ids:
|
||||
if meal_id.select_revoke == 'done':
|
||||
raise UserError("该记录已撤销")
|
||||
meal_id.revoke()
|
||||
@@ -994,6 +994,8 @@ class YuthonVacationReports(models.Model):
|
||||
'used_this_year1': last_month_record.used_this_year1,
|
||||
}
|
||||
rec.write(inherit_vals)
|
||||
if rec.meal_number:
|
||||
self._update_meal_lines(rec, [rec], rec.meal_number)
|
||||
if rec.leave:
|
||||
leave_hours = rec.leave * 8
|
||||
self._update_leave_lines(rec, [rec], leave_hours)
|
||||
@@ -1325,6 +1327,24 @@ class YuthonVacationReports(models.Model):
|
||||
'text': f"上月额度继承",
|
||||
})
|
||||
|
||||
def _update_meal_lines(self, report, allocations, number_of_hours_display):
|
||||
for alloc in allocations:
|
||||
existing_line = self.env['vacation.meal.line'].search([
|
||||
('vacation_id', '=', report.id),
|
||||
('employee_id', '=', report.employee_id.id),
|
||||
('text', '=', '上月额度继承'),
|
||||
], limit=1)
|
||||
if existing_line:
|
||||
continue
|
||||
self.env['vacation.meal.line'].sudo().create({
|
||||
'vacation_id': report.id,
|
||||
'employee_id': report.employee_id.id,
|
||||
'update_type': 'add',
|
||||
'update_date': fields.Date.today(),
|
||||
'update_lines': number_of_hours_display,
|
||||
'text': f"上月额度继承",
|
||||
})
|
||||
|
||||
def log(self):
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
@@ -1883,34 +1903,64 @@ class VacationMealLine(models.Model):
|
||||
rec._compute_employee_id()
|
||||
rec._compute_overtime()
|
||||
|
||||
@api.model
|
||||
def confirm(self):
|
||||
now = datetime.now()
|
||||
current_month = now.month
|
||||
current_year = now.year
|
||||
if current_month == 1:
|
||||
last_month = 12
|
||||
last_month_year = current_year - 1
|
||||
else:
|
||||
last_month = current_month - 1
|
||||
last_month_year = current_year
|
||||
last_month_first_day = datetime(last_month_year, last_month, 1)
|
||||
current_month_first_day = datetime(current_year, current_month, 1)
|
||||
valid_leaves = self.search([
|
||||
('start_date', '>=', fields.Datetime.to_string(last_month_first_day)),
|
||||
('start_date', '<', fields.Datetime.to_string(current_month_first_day)),
|
||||
('id', 'in', self.ids)
|
||||
])
|
||||
if valid_leaves:
|
||||
valid_leaves.write({'is_filing': True})
|
||||
valid_leaves = self.env['vacation.meal.line'].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
emp_month_summary = {}
|
||||
for rec in valid_leaves:
|
||||
rec_year = rec.start_time.year
|
||||
rec_month = rec.start_time.month
|
||||
rec.write({'is_filing': True})
|
||||
emp_id = rec.employee_id.id
|
||||
meal_active_vals = {
|
||||
'line_id': rec.id,
|
||||
'meal_name': rec.meal_name,
|
||||
'employee_id': emp_id,
|
||||
'workflow_id': rec.workflow_id.id if rec.workflow_id else False,
|
||||
'start_time': rec.start_time,
|
||||
'end_time': rec.end_time,
|
||||
'duration': rec.duration,
|
||||
'update_lines': rec.update_lines,
|
||||
'reasons': rec.reasons,
|
||||
'meal': rec.meal,
|
||||
'carry_forward_date': fields.Date.today(),
|
||||
'carry_forward_state': 'completed',
|
||||
'select_revoke': 'to_do'
|
||||
}
|
||||
self.env['vacation.meal.active'].create(meal_active_vals)
|
||||
|
||||
summary_key = (emp_id, rec_year, rec_month)
|
||||
if summary_key not in emp_month_summary:
|
||||
emp_month_summary[summary_key] = 0.0
|
||||
emp_month_summary[summary_key] += rec.update_lines or 0.0
|
||||
|
||||
# 4. 第二步:遍历汇总结果,为每个【员工+年月】创建一条vacation.over.line
|
||||
for (emp_id, rec_year, rec_month), total_amount in emp_month_summary.items():
|
||||
if total_amount <= 1e-6:
|
||||
continue
|
||||
report_id = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', emp_id),
|
||||
('vacation_date', '=', fields.Date.from_string(f'{rec_year}-{rec_month}-01'))
|
||||
], limit=1)
|
||||
if report_id:
|
||||
self.env['vacation.meal.line'].create([{
|
||||
'vacation_id': report_id.id,
|
||||
'employee_id': emp_id,
|
||||
'update_type': 'reduce',
|
||||
'update_lines': total_amount,
|
||||
'update_date': fields.Date.today(),
|
||||
'is_void': False,
|
||||
'text': f'{rec_month}月份误餐结转',
|
||||
}])
|
||||
|
||||
@api.depends('workflow_record_id')
|
||||
def _compute_overtime(self):
|
||||
for rec in self:
|
||||
rec.start_date = False
|
||||
res_model = rec.workflow_record_id.res_model
|
||||
rec.meal = 'yes'
|
||||
res_id = rec.workflow_record_id.res_id
|
||||
if res_model and res_id and res_model in self.env:
|
||||
if res_model and res_id and res_model in self.env and rec.update_type == 'add':
|
||||
if res_model == 'overtime.approval':
|
||||
overtime_id = rec.env[res_model].search([('id', '=', res_id)], limit=1)
|
||||
if overtime_id:
|
||||
@@ -1940,7 +1990,7 @@ class VacationMealLine(models.Model):
|
||||
rec.start_time = start_time
|
||||
rec.end_time = end_time
|
||||
rec.meal = go_approval_id.meal
|
||||
|
||||
rec.workflow_id = rec.workflow_record_id.workflow_id.id
|
||||
rec.meal_name = rec.workflow_record_id.name or ''
|
||||
|
||||
|
||||
|
||||
@@ -91,4 +91,5 @@ access_yuthon_parenting_allocate,yuthon.parenting.allocate,model_yuthon_parentin
|
||||
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_overtime_active_line,overtime.active.line,model_overtime_active_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
|
||||
access_vacation_meal_active,vacation.meal.active,model_vacation_meal_active,base.group_user,1,1,1,1
|
||||
|
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="view_vacation_meal_active_tree" model="ir.ui.view">
|
||||
<field name="name">vacation.meal.active.tree</field>
|
||||
<field name="model">vacation.meal.active</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="误餐记录" editable="bottom">
|
||||
<header>
|
||||
<button name="revoke" type="object" string="批量撤销" dclass="oe_highlight"/>
|
||||
</header>
|
||||
<field name="meal_name"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="workflow_id"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="duration"/>
|
||||
<field name="update_lines"/>
|
||||
<field name="reasons"/>
|
||||
<field name="meal"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_forward_state"/>
|
||||
<field name="line_id" column_invisible="1"/>
|
||||
<field name="select_revoke" widget="badge"
|
||||
decoration-danger="select_revoke == 'done'" decoration-success="select_revoke == 'to_do'"/>
|
||||
<button name="revoke" type="object" string="撤销" class="oe_highlight" invisible="select_revoke == 'done'"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_vacation_meal_active_action" model="ir.actions.act_window">
|
||||
<field name="name">误餐费归档</field>
|
||||
<field name="res_model">vacation.meal.active</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -4,9 +4,12 @@
|
||||
<field name="name">vacation.meal.line.tree</field>
|
||||
<field name="model">vacation.meal.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="误餐情况" create="false" delete="false" js_class="custom_vacation_meal_button">
|
||||
<field name="employee_id"/>
|
||||
<field name="meal_name"/>
|
||||
<tree string="误餐情况" create="false" delete="false">
|
||||
<header>
|
||||
<button name="confirm" type="object" string="归档" dclass="oe_highlight"/>
|
||||
</header>
|
||||
<field name="meal_name" column_invisible="1"/>
|
||||
<field name="employee_id" string="申请人"/>
|
||||
<field name="workflow_id"/>
|
||||
<field name="start_date" column_invisible="1"/>
|
||||
<field name="start_time"/>
|
||||
@@ -282,12 +285,12 @@
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="0"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<field name="update_lines"/>
|
||||
<field name="valid_date"/>
|
||||
<field name="adjust_date"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary"
|
||||
groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object"
|
||||
@@ -347,18 +350,6 @@
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<!-- <page string="出勤消息日志" invisible="1">-->
|
||||
<!-- <field name="attendance_message_log_ids">-->
|
||||
<!-- <tree editable="bottom" create="false" edit="false" delete="false">-->
|
||||
<!-- <field name="vacation_id" column_invisible="1"/>-->
|
||||
<!-- <field name="employee_id"/>-->
|
||||
<!-- <field name="update_date"/>-->
|
||||
<!-- <field name="message_type"/>-->
|
||||
<!-- <field name="message_url"/>-->
|
||||
<!-- <button name="unlink" string="删除" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </page>-->
|
||||
<page string="管理员修改字段" groups="base.group_system">
|
||||
<group col="2">
|
||||
<group>
|
||||
@@ -700,7 +691,7 @@
|
||||
<field name="name">误餐情况</field>
|
||||
<field name="res_model">vacation.meal.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('is_filing','=', False)]</field>
|
||||
<field name="domain">[('is_filing','=', False),('update_type','=','add')]</field>
|
||||
<field name="context">{'search_default_now_month': 1,}</field>
|
||||
<field name="search_view_id" ref="view_yuthon_vacation_meal_search"/>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
@@ -713,16 +704,6 @@
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.update_line()</field>
|
||||
</record>
|
||||
<record id="view_yuthon_vacation_meal_active_action" model="ir.actions.act_window">
|
||||
<field name="name">误餐归档</field>
|
||||
<field name="res_model">vacation.meal.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('is_filing','=', True)]</field>
|
||||
<field name="context">{'search_default_now_month': 1, 'search_default_group_by_employee_id':1}</field>
|
||||
<field name="search_view_id" ref="view_yuthon_vacation_meal_search"/>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_vacation_meal_line_tree')}),]"/>
|
||||
</record>
|
||||
<record id="view_yuthon_vacation_reports_action" model="ir.actions.act_window">
|
||||
<field name="name">考勤确认单台账</field>
|
||||
<field name="res_model">yuthon.vacation.reports</field>
|
||||
|
||||
@@ -760,7 +760,7 @@
|
||||
<menuitem id="yuthon_menu_active_menu"
|
||||
parent="yuthon_vacation_active_menu"
|
||||
name="误餐归档"
|
||||
action="yuthon_hr_attendance.view_yuthon_vacation_meal_active_action"
|
||||
action="yuthon_hr_attendance.view_vacation_meal_active_action"
|
||||
sequence="30"
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user