Merge pull request #270 from expsa/abuzar_task_hr

add task permation and fix holiday
This commit is contained in:
AbuzarExp 2024-07-18 16:29:47 +03:00 committed by GitHub
commit f7770af315
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 89 additions and 69 deletions

View File

@ -22,12 +22,9 @@ class HrPersonalPermission(models.Model):
duration = fields.Float(compute='get_duration_no' ,store=True)
employee_contract_id = fields.Many2one(comodel_name='hr.contract.type')
balance = fields.Float(related='employee_id.contract_id.working_hours.permission_hours')
permission_number = fields.Float(store=True, readonly=True,
help='The Remaining Number of Hours permission This Month')
permission_number = fields.Float(store=True, readonly=True, help='The Remaining Number of Hours permission This Month')
early_exit = fields.Boolean()
mission_purpose = fields.Text()
employee_no = fields.Char(related='employee_id.emp_no', readonly=True)
job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
department_id = fields.Many2one(related='employee_id.department_id', readonly=True)
@ -35,20 +32,40 @@ class HrPersonalPermission(models.Model):
attach_ids = fields.One2many('ir.attachment', 'personal_permission_id')
approved_by = fields.Many2one(comodel_name='res.users')
refused_by = fields.Many2one(comodel_name='res.users')
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
state = fields.Selection(
[('draft', _('Draft')), ('send', _('Waiting Direct Manager')), ('direct_manager', _('Wait HR Department')),
('approve', _('Approved'))
, ('refused', _('Refused'))], default="draft", tracking=True)
type_exit = fields.Selection(
[('early_exit', _('Early Exit')), ('late entry', _('Late Entry')), ('during work', _('During Work'))],
default="early_exit")
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id(),domain=[('state', '=', 'open')])
state = fields.Selection([('draft', _('Draft')), ('send', _('Waiting Direct Manager')), ('direct_manager', _('Wait HR Department')),('approve', _('Approved')), ('refused', _('Refused'))], default="draft", tracking=True)
type_exit = fields.Selection([('early_exit', _('Early Exit')), ('late entry', _('Late Entry')), ('during work', _('During Work'))],default="early_exit")
company_id = fields.Many2one('res.company',string="Company", default=lambda self: self.env.user.company_id)
time_permission_from = fields.Float(string="Permission From (24h format)", help="Time in 24-hour format (e.g., 13.5 for 1:30 PM)")
time_permission_to = fields.Float(string="Permission To (24h format)", help="Time in 24-hour format (e.g., 15.75 for 3:45 PM)")
@api.onchange('time_permission_from', 'time_permission_to', 'date')
def _onchange_time(self):
for record in self:
if (not record.time_permission_from < record.time_permission_to):
record.time_permission_to = record.time_permission_from + 0.5
record.time_permission_from = record.time_permission_from
if record.date:
date_from = self._combine_date_and_time(record.date, record.time_permission_from)
record.date_from = date_from
if record.date:
date_to = self._combine_date_and_time(record.date, record.time_permission_to)
record.date_to = date_to
def _combine_date_and_time(self, date, time_float):
""" Combine a date and a float time (e.g. 13.5) into a datetime object. """
hours = int(time_float)
minutes = int((time_float - hours) * 60)
import pytz
date_time = datetime.combine(date, datetime.min.time()) + timedelta(hours=hours, minutes=minutes)
# if time_float > 0:
date_time = fields.Datetime.to_string(pytz.timezone(self.env.context['tz']).localize(fields.Datetime.from_string(date_time), is_dst=None).astimezone(pytz.utc))
# date_time = fields.Datetime.to_string(pytz.timezone(self.env.context['tz']).localize(fields.Datetime.from_string(date_time), is_dst=None).astimezone(pytz.utc) + timedelta(hours=24))
return date_time
@api.model
def create(self, vals):
new_record = super(HrPersonalPermission, self).create(vals)
@ -80,6 +97,7 @@ class HrPersonalPermission(models.Model):
@api.depends('date_from', 'date_to')
def get_duration_no(self):
for item in self:
item._onchange_time()
if item.date_from and item.date_to:
start_date_value = datetime.strptime(str(item.date_from), "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(str(item.date_to), "%Y-%m-%d %H:%M:%S")
@ -94,6 +112,7 @@ class HrPersonalPermission(models.Model):
@api.onchange('date_to', 'date_from', 'employee_id')
def permission_number_decrement(self):
for item in self:
item._onchange_time()
if item.employee_id:
if not item.employee_id.first_hiring_date:
raise exceptions.Warning(

View File

@ -7,7 +7,7 @@
<field name="view_mode">tree,form,calendar</field>
</record>
<record model="ir.ui.view" id="view_permission_calendar">
<record model="ir.ui.view" id="view_permission_calendar">
<field name="name">hr.personal.permission.calendar</field>
<field name="model">hr.personal.permission</field>
<field name="arch" type="xml">
@ -25,58 +25,55 @@
<field name="arch" type="xml">
<form>
<header>
<button name="send" string="Submit" class="oe_highlight" type="object"
states="draft" groups="base.group_user"/>
<button name="send" string="Submit" class="oe_highlight" type="object" states="draft" groups="base.group_user"/>
<button name="direct_manager" string="Direct Manager Approve" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="direct_manager" string="Direct Manager Approve" class="oe_highlight" type="object" states="send" groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object" states="send" groups="hr_base.group_division_manager"/>
<button name="approve" string="HR Approve" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="approve" groups="hr.group_hr_user"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="refused" groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<button name="approve" string="HR Approve" class="oe_highlight" type="object" states="direct_manager" groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object" states="direct_manager" groups="hr.group_hr_user"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object" states="approve" groups="hr.group_hr_user"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object" states="refused" groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group string="Permission Info">
<field name="date" string="Date Request"
attrs="{'readonly':[('state','!=','draft')],'required':1}"/>
<field name="date_from" string="Date From"
attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
<field name="date_to" string="Date To"
attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
<field name="date" string="Date Request" attrs="{'readonly':[('state','!=','draft')],'required':1}"/>
<label for='time_permission_from' string="Time"/>
<div class="row">
<div class="col-6">
<label for='time_permission_from' string="Time from"/>
<field name="time_permission_from" widget="float_time" attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
</div>
<div class="col-6">
<label for='time_permission_to' string="Time To"/>
<field name="time_permission_to" widget="float_time" attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
</div>
</div>
<field name="date_from" invisible="1" string="Date From" attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
<field name="date_to" invisible="1" string="Date To" attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
<field name="duration" string="Duration" attrs="{'readonly':1}" widget="float_time"/>
<field name="balance" string="Permission Limit" readonly="1" widget="float_time"/>
<field name="permission_number" force_save="True" string="Permission Per Month" widget="float_time"/>
<field name="type_exit" string="Type Exit"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="type_exit" string="Type Exit" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group string="Employee Info">
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="from_hr_department" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee"
attrs="{'readonly': ['|',('from_hr_department','=',False),('state','!=','draft')],'required':True}"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="from_hr_department" string="Another Employee" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee" attrs="{'readonly': ['|',('from_hr_department','=',False),('state','!=','draft')],'required':True}"/>
<field name="employee_no" string="Employee No" readonly="1"/>
<field name="job_id" string="Job Title" readonly="1"/>
<field name="department_id" string="Department" readonly="1"/>
</group>
</group>
<group>
<field name="mission_purpose" string="Reasons"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="mission_purpose" string="Reasons" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<!--notebook>
<page string="Attachments" name="attachments">
<field name="attach_ids" string="Attachments"
attrs="{'readonly':[('state','!=','draft')]}">
<field name="attach_ids" string="Attachments" attrs="{'readonly':[('state','!=','draft')]}">
<tree editable="bottom">
<field name="name" string="attachment Name"/>
<field name="datas" string="file content"/>
@ -84,15 +81,12 @@
</field>
</page>
<page string="Refusal Causes" name="refusal_causes">
<field name="refuse_cause" placeholder="Refuse Cause .........."
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="refuse_cause" placeholder="Refuse Cause .........." attrs="{'readonly':[('state','!=','draft')]}"/>
</page>
<page string="Information" name="information">
<group>
<field name="approved_by" string="Approved By"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="refused_by" string="Refused By"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="approved_by" string="Approved By" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="refused_by" string="Refused By" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
</page>
</notebook-->

View File

@ -109,21 +109,23 @@ class HrHolidaysStatus(models.Model):
leaves = self.browse(leave_ids)
sort_key = lambda l: (l.leave_type, l.sickness_severity, l.virtual_remaining_leaves)
employee_id = self._context.get('employee_id')
balance = self.env['hr.holidays'].search([
('employee_id', '=', int(employee_id)),
('holiday_status_id.leave_type', '!=', 'sick'),
('type', '=', 'add'),
('check_allocation_view', '=', 'balance')
]).mapped('holiday_status_id')
balance_sick = self.env['hr.holidays'].search([
('employee_id', '=', int(employee_id)),
('holiday_status_id.leave_type', '=', 'sick'),
('type', '=', 'add'),
('check_allocation_view', '=', 'balance'),
('remaining_leaves', '>', 0)
]).mapped('holiday_status_id').sorted(key=lambda eval: eval.sickness_severity, reverse=False)
balance_sick = balance_sick and balance_sick[0] or balance_sick
leaves = balance | balance_sick
type_holiday = self._context.get('type')
if type_holiday == "remove":
balance = self.env['hr.holidays'].search([
('employee_id', '=', int(employee_id)),
('holiday_status_id.leave_type', '!=', 'sick'),
('type', '=', 'add'),
('check_allocation_view', '=', 'balance')
]).mapped('holiday_status_id')
balance_sick = self.env['hr.holidays'].search([
('employee_id', '=', int(employee_id)),
('holiday_status_id.leave_type', '=', 'sick'),
('type', '=', 'add'),
('check_allocation_view', '=', 'balance'),
('remaining_leaves', '>', 0)
]).mapped('holiday_status_id').sorted(key=lambda eval: eval.sickness_severity, reverse=False)
balance_sick = balance_sick and balance_sick[0] or balance_sick
leaves = balance | balance_sick
return leaves.sorted(key=sort_key, reverse=False).ids
return leave_ids

View File

@ -24,6 +24,11 @@
hr_base.group_division_manager,hr_holidays_community.group_hr_holidays_user
</attribute>
</xpath>
<xpath expr="//field[@name='holiday_status_id']" position="attributes">
<attribute name="context">
{'employee_id':employee_id,'type':type}
</attribute>
</xpath>
<xpath expr="//field[@name='department_id']" position="attributes">
<attribute name="readonly">True</attribute>
<attribute name="required">True</attribute>