4

I created the field half_day_allowed in hr_leave_rules.py

from odoo import models, fields, api, _

class HRLeaveRules(models.Model):
    _name = 'hr_leave_rules.leave_rules'

    half_day_allowed = fields.Selection([
        ('yes',"Yes"),
        ('no',"No")],
        string="Half Day Allowed", required=True)

and also,I have inherited the fields get_number_of_days which calculates leave applied is for how many days and holiday_status_id which indicates leave type . what I am trying to do is if for particular holiday_status_id if half_day_allowed is 'yes' then in get_number_of_days it should take float values otherwise it will take integer value. For this I tried the below code but it is not working.plz help me out.

leave_type.py

from odoo import fields, models, api, _
from math import ceil
from datetime import timedelta
from openerp.exceptions import UserError

HOURS_PER_DAY = 8

class leave(models.Model):
    _inherit = "hr.holidays"


    @api.onchange('number_of_days_temp')
    def _holiday_status_id(self):

        current = self.env['hr_leave_rules.leave_rules'].search([(
                'holiday_status_id','=',self.holiday_status_id.id)])

    @api.onchange('date_from')
    def _onchange_date_from(self):

        date_from = self.date_from
        date_to = self.date_to

        if date_from and not date_to:
            date_to_with_delta = fields.Datetime.from_string(date_from) + timedelta(hours=HOURS_PER_DAY)
            self.date_to = str(date_to_with_delta)
            current = self.env['hr_leave_rules.leave_rules'].search([(
                    'holiday_status_id','=',self.holiday_status_id.id)])

            if current.half_day_allowed == 'yes':
                if (date_to and date_from) and (date_from <= date_to):
                    self.number_of_days_temp = self._get_number_of_days(
                            date_from, date_to, self.employee_id.id)
                else:
                    self.number_of_days_temp = 0
            else:
                if (date_to and date_from) and (date_from <= date_to):
                        self.number_of_days_temp = ceil(self._get_number_of_days(
                            date_from, date_to, self.employee_id.id))
                else:
                    self.number_of_days_temp = 0

    @api.onchange('date_to')
    def _onchange_date_to(self):

        date_from = self.date_from
        date_to = self.date_to

        current = self.env['hr_leave_rules.leave_rules'].search([(
                'holiday_status_id','=',self.holiday_status_id.id)])

        if current.half_day_allowed == 'yes':
            if (date_to and date_from) and (date_from <= date_to):
                self.number_of_days_temp = self._get_number_of_days(
                    date_from, date_to, self.employee_id.id)
            else:
                self.number_of_days_temp = 0
        else:
            if (date_to and date_from) and (date_from <= date_to):
                self.number_of_days_temp = ceil(self._get_number_of_days(
                    date_from, date_to, self.employee_id.id))
            else:
                self.number_of_days_temp = 0
Chavada Viki
  • 1,514
  • 1
  • 12
  • 22

1 Answers1

0

Where to begin...

Firstly, if you have a field that is Yes/No, it should be defined as a Boolean field, not as a Char field. Fields Documentation. It will allow you to do simpler if/else logic, not to mention it's just a better practice.

if half_day_allowed:
    # Do this way
else:
    # Do that way

Secondly, if you have repetitive code, you should break it into its own method for readability. Don't repeat yourself.

You've repeated this entire section twice:

if half_day_allowed == 'yes':
    if (date_to and date_from) and (date_from <= date_to):
        self.number_of_days_temp = self._get_number_of_days(
                date_from, date_to, self.employee_id.id)
    else:
        self.number_of_days_temp = 0
else:
    if (date_to and date_from) and (date_from <= date_to):
            self.number_of_days_temp = ceil(self._get_number_of_days(
                date_from, date_to, self.employee_id.id))
    else:
        self.number_of_days_temp = 0

Instead, just create a new method and call it when you need it.

@api.multi
def get_number_of_days_temp(self, half_day_allowed=False):
    self.ensure_one()
    if half_day_allowed == 'yes':
        # Do this
    else:
        # Do that

@api.onchange('date_from')
def _onchange_date_from(self):
    ...
    self.number_of_days_temp = self.get_number_of_days_temp(current.half_day_allowed)

@api.onchange('date_to')
def _onchange_date_to(self):
    ...
    self.number_of_days_temp = self.get_number_of_days_temp(current.half_day_allowed)

Finally, to determine what the problem is with not getting the expected results, we need more information from you. All you've said so far is:

I tried the below code but it is not working.

Its not showing correct get_number_of_days in both the cases i.e., in 'yes' and 'no'

This is not helpful to determine the problem. Is there an error message? Is it returning invalid data? If so, what are the inputs and outputs and what are expecting it should be?

Without knowing anything further, the only guess I can make is that your number_of_days_temp field (which you haven't included the field definition in your question) is defined as an Integer field, in which case it will always ignore the decimals. It must be defined as a Float for this to work.

Community
  • 1
  • 1
travisw
  • 2,052
  • 1
  • 14
  • 27