Пример #1
0
    def _get_day_attendances(self, day_date, start_time, end_time):
        """ Given a day date, return matching attendances. Those can be limited
        by starting and ending time objects. """
        self.ensure_one()
        weekday = day_date.weekday()
        attendances = self.env['resource.calendar.attendance']

        for attendance in self.attendance_ids.filtered(
                lambda att: int(att.dayofweek) == weekday and not (
                    att.date_from and fields.Date.from_string(att.date_from) >
                    day_date) and not (att.date_to and fields.Date.from_string(
                        att.date_to) < day_date)):
            if start_time and float_to_time(attendance.hour_to) < start_time:
                continue
            if end_time and float_to_time(attendance.hour_from) > end_time:
                continue
            attendances |= attendance

        for attendance_expt in self.attendance_ids_expt.filtered(
                lambda att: int(att.dayofweek) == weekday and not (
                    att.date_from and fields.Date.from_string(att.date_from) >
                    day_date) and not (att.date_to and fields.Date.from_string(
                        att.date_to) < day_date)):
            if start_time and float_to_time(
                    attendance_expt.hour_to) < start_time:
                continues
            if end_time and float_to_time(
                    attendance_expt.hour_from) > end_time:
                continue
            attendances |= attendance_expt

        return attendances
Пример #2
0
    def _onchange_date(self):
        if self.fal_date_from and self.fal_date_to:
            domain = [('calendar_id', '=', self.fal_fix_date_id.resource_calendar_id.id or self.env.user.company_id.resource_calendar_id.id)]
            attendances = self.env['resource.calendar.attendance'].search(
                domain, order='dayofweek, day_period DESC')

            # find first attendance coming after first_day
            attendance_from = next((
                att for att in attendances if int(
                    att.dayofweek
                ) >= self.fal_date_from.weekday()), attendances[0])
            # find last attendance coming before last_day
            attendance_to = next((
                att for att in reversed(
                    attendances
                ) if int(
                    att.dayofweek
                ) <= self.fal_date_to.weekday()), attendances[-1])

            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

            tz = self.env.user.tz if self.env.user.tz else 'UTC'
            self.fal_opening_date = timezone(tz).localize(
                datetime.combine(self.fal_date_from, hour_from)
            ).astimezone(UTC).replace(tzinfo=None)
            self.fal_ending_date = timezone(tz).localize(
                datetime.combine(self.fal_date_to, hour_to)
            ).astimezone(UTC).replace(tzinfo=None)
Пример #3
0
 def _compute_late_today(self):
     get_config_timekeeping = self.env['manager.attendance'].search([],
                                                                    limit=1)
     for attendance in self:
         if attendance.check_in and len(get_config_timekeeping) > 0:
             check_in = attendance.check_in.astimezone(
                 timezone(get_config_timekeeping.time_zone))
             if datetime.combine(
                     check_in.date(), check_in.time()) < datetime.combine(
                         check_in.date(),
                         float_to_time(get_config_timekeeping.hour_am_to)):
                 late_today = (datetime.combine(
                     check_in.date(), check_in.time()) - datetime.combine(
                         check_in.date(),
                         float_to_time(get_config_timekeeping.hour_am_from))
                               ).total_seconds() / 60.0
             else:
                 late_today = (datetime.combine(
                     check_in.date(), check_in.time()) - datetime.combine(
                         check_in.date(),
                         float_to_time(get_config_timekeeping.hour_pm_from))
                               ).total_seconds() / 60.0
             attendance.late_today = round(late_today, 2)
         else:
             attendance.late_today = False
Пример #4
0
    def _compute_is_in_opening_hours(self):
        """ Opening hours: hour_from and hour_to are given within event TZ or UTC.
        Now() must therefore be computed based on that TZ. """
        for sponsor in self:
            if not sponsor.event_id.is_ongoing:
                sponsor.is_in_opening_hours = False
            elif not sponsor.hour_from or not sponsor.hour_to:
                sponsor.is_in_opening_hours = True
            else:
                event_tz = timezone(sponsor.event_id.date_tz)
                # localize now, begin and end datetimes in event tz
                dt_begin = sponsor.event_id.date_begin.astimezone(event_tz)
                dt_end = sponsor.event_id.date_end.astimezone(event_tz)
                now_utc = utc.localize(
                    fields.Datetime.now().replace(microsecond=0))
                now_tz = now_utc.astimezone(event_tz)

                # compute opening hours
                opening_from_tz = event_tz.localize(
                    datetime.combine(now_tz.date(),
                                     float_to_time(sponsor.hour_from)))
                opening_to_tz = event_tz.localize(
                    datetime.combine(now_tz.date(),
                                     float_to_time(sponsor.hour_to)))

                opening_from = max([dt_begin, opening_from_tz])
                opening_to = min([dt_end, opening_to_tz])

                sponsor.is_in_opening_hours = opening_from <= now_tz < opening_to
Пример #5
0
    def _validate_leave_request(self):
        """ Timesheet will be generated on leave validation only if a timesheet_project_id and a
            timesheet_task_id are set on the corresponding leave type. The generated timesheet will
            be attached to this project/task.
        """
        # create the timesheet on the vacation project
        for holiday in self.filtered(
                lambda request: request.holiday_type == 'employee'):

            work_hours_data = holiday.employee_id.list_work_time_per_day(
                fields.Datetime.from_string(holiday.date_from),
                fields.Datetime.from_string(holiday.date_to),
            )
            #             raise UserError(_(work_hours_data))
            for index, (day_date,
                        work_hours_count) in enumerate(work_hours_data):

                if holiday.request_unit_hours:
                    hour_from = float_to_time(
                        abs(holiday.request_hour_from) -
                        0.5 if holiday.request_hour_from < 0 else holiday.
                        request_hour_from)
                    hour_to = float_to_time(
                        abs(holiday.request_hour_to) -
                        0.5 if holiday.request_hour_to < 0 else holiday.
                        request_hour_to)
                    tz = self.env.user.tz if self.env.user.tz and not holiday.request_unit_custom else 'US/Central'  # custom -> already in UTC
                    check_in = timezone(tz).localize(
                        datetime.combine(
                            holiday.request_date_from,
                            hour_from)).astimezone(UTC).replace(tzinfo=None)
                    check_out = timezone(tz).localize(
                        datetime.combine(
                            holiday.request_date_to,
                            hour_to)).astimezone(UTC).replace(tzinfo=None)
                else:
                    check_in = datetime(day_date.year, day_date.month,
                                        day_date.day, 8, 0, 0)
                    check_out_time = 8 + int(work_hours_count)
                    check_out = datetime(day_date.year, day_date.month,
                                         day_date.day, check_out_time, 0, 0)
#                 raise UserError(check_out)

                self.env['hr.attendance'].create({
                    'check_in':
                    check_in,
                    'check_out':
                    check_out,
                    'worked_hours':
                    work_hours_count,
                    'employee_id':
                    holiday.employee_id.id,
                    'hour_type':
                    holiday.holiday_status_id.id,
                    'status':
                    'open',
                })

        return super(HrLeaves, self)._validate_leave_request()
Пример #6
0
    def _onchange_request_parameters(self, vals):
        if not vals.get('request_date_from', False):
            vals.update({'date_from': False})
            return vals

        if vals.get('request_unit_half', False):
            vals.update({'request_date_to': vals.get('request_date_from')})

        if not vals.get('request_date_to', False):
            vals.update({'date_to': False})
            return vals

        employee_id = False
        if vals.get('employee_id', False):
            employee_id = request.env['hr.employee'].sudo().browse(
                [vals.get('employee_id')])

        resource_calendar_id = employee_id.resource_calendar_id.id if employee_id else request.env.user.company_id.resource_calendar_id.id

        domain = [('calendar_id', '=', resource_calendar_id)]
        attendances = request.env['resource.calendar.attendance'].sudo(
        ).search(domain, order='dayofweek, day_period DESC')

        # find first attendance coming after first_day
        attendance_from = next(
            (att for att in attendances
             if int(att.dayofweek) >= vals.get('request_date_from').weekday()),
            attendances[0])
        # find last attendance coming before last_day
        attendance_to = next(
            (att for att in reversed(attendances)
             if int(att.dayofweek) <= vals.get('request_date_to').weekday()),
            attendances[-1])

        if vals.get('request_unit_half', False):
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_from.hour_to)
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = request.env.user.tz if request.env.user.tz else 'UTC'  # custom -> already in UTC
        date_from = timezone(tz).localize(
            datetime.combine(vals.get('request_date_from'),
                             hour_from)).astimezone(UTC).replace(tzinfo=None)
        date_to = timezone(tz).localize(
            datetime.combine(vals.get('request_date_to'),
                             hour_to)).astimezone(UTC).replace(tzinfo=None)
        vals.update({'date_from': date_from})
        vals.update({'date_to': date_to})

        return vals
Пример #7
0
    def _onchange_request_parameters(self):
        if not self.request_date_from:
            self.date_from = False
            return

        if self.request_unit_half or self.request_unit_hours:
            self.request_date_to = self.request_date_from

        if not self.request_date_to:
            self.date_to = False
            return

        domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id
                   or self.env.user.company_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].search(
            domain, order='dayofweek, day_period DESC')

        # find first attendance coming after first_day
        attendance_from = next(
            (att for att in attendances
             if int(att.dayofweek) >= self.request_date_from.weekday()),
            attendances[0])
        # find last attendance coming before last_day
        attendance_to = next(
            (att for att in reversed(attendances)
             if int(att.dayofweek) <= self.request_date_to.weekday()),
            attendances[-1])

        if self.request_unit_half:
            if self.request_date_from_period == 'am':
                hour_from = float_to_time(attendance_from.hour_from)
                hour_to = float_to_time(attendance_from.hour_to)
            else:
                hour_from = float_to_time(attendance_to.hour_from)
                hour_to = float_to_time(attendance_to.hour_to)
        elif self.request_unit_hours:
            # This hack is related to the definition of the field, basically we convert
            # the negative integer into .5 floats
            hour_from = float_to_time(
                abs(self.request_hour_from) -
                0.5 if self.request_hour_from < 0 else self.request_hour_from)
            hour_to = float_to_time(
                abs(self.request_hour_to) -
                0.5 if self.request_hour_to < 0 else self.request_hour_to)
        elif self.request_unit_custom:
            hour_from = self.date_from.time()
            hour_to = self.date_to.time()
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC'  # custom -> already in UTC
        self.date_from = timezone(tz).localize(
            datetime.combine(self.request_date_from,
                             hour_from)).astimezone(UTC).replace(tzinfo=None)
        self.date_to = timezone(tz).localize(
            datetime.combine(self.request_date_to,
                             hour_to)).astimezone(UTC).replace(tzinfo=None)
        self._onchange_leave_dates()
Пример #8
0
    def _onchange_request_parameters(self):
        if not self.request_date_from:
            self.date_from = False
            return

        if self.request_unit_half or self.request_unit_hours:
            self.request_date_to = self.request_date_from

        if not self.request_date_to:
            self.date_to = False
            return

        domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id
                   or self.env.user.company_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].search(
            domain, order='dayofweek, day_period DESC')

        # find first attendance coming after first_day
        attendance_from = next(
            (att for att in attendances
             if int(att.dayofweek) >= self.request_date_from.weekday()),
            attendances[0])
        # find last attendance coming before last_day
        attendance_to = next(
            (att for att in reversed(attendances)
             if int(att.dayofweek) <= self.request_date_to.weekday()),
            attendances[-1])

        if self.request_unit_half:
            if self.request_date_from_period == 'am':
                hour_from = float_to_time(attendance_from.hour_from)
                hour_to = float_to_time(attendance_from.hour_to)
            else:
                hour_from = float_to_time(attendance_to.hour_from)
                hour_to = float_to_time(attendance_to.hour_to)
        elif self.request_unit_hours:
            hour_from = float_to_time(self.request_hour_from)
            hour_to = float_to_time(self.request_hour_to)
        elif self.request_unit_custom:
            hour_from = self.date_from.time()
            hour_to = self.date_to.time()
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC'  # custom -> already in UTC
        #################################################################### edit
        datefrom = timezone(tz).localize(
            datetime.combine(fields.Date.from_string(self.request_date_from),
                             hour_from)).astimezone(UTC).replace(tzinfo=None)
        date_to = timezone(tz).localize(
            datetime.combine(fields.Date.from_string(self.request_date_to),
                             hour_to)).astimezone(UTC).replace(tzinfo=None)
        self.date_from = datefrom.date()
        # print ("datefrom")
        self.date_to = date_to.date()
Пример #9
0
    def _onchange_request_parameters(self):
        if not self.request_date_from:
            self.date_from = False
            return

        if self.holiday_status_id and self.holiday_status_id.name in HOLIDAY_SAMEDAY_LIST:
            self.request_date_to = self.request_date_from
            
        if self.holiday_status_id and self.holiday_status_id.name in HOLIDAY_HALFDAY_LIST:
            self.request_unit_half=True
        else:
            self.request_unit_half=False

        if self.request_unit_half or self.request_unit_hours:
            self.request_date_to = self.request_date_from

        if not self.request_date_to:
            self.date_to = False
            return

        domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id or self.env.user.company_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].read_group(domain, ['ids:array_agg(id)', 'hour_from:min(hour_from)', 'hour_to:max(hour_to)', 'dayofweek', 'day_period'], ['dayofweek', 'day_period'], lazy=False)

        # Must be sorted by dayofweek ASC and day_period DESC
        attendances = sorted([DummyAttendance(group['hour_from'], group['hour_to'], group['dayofweek'], group['day_period']) for group in attendances], key=lambda att: (att.dayofweek, att.day_period != 'morning'))

        default_value = DummyAttendance(0, 0, 0, 'morning')

        # find first attendance coming after first_day
        attendance_from = next((att for att in attendances if int(att.dayofweek) >= self.request_date_from.weekday()), attendances[0] if attendances else default_value)
        # find last attendance coming before last_day
        attendance_to = next((att for att in reversed(attendances) if int(att.dayofweek) <= self.request_date_to.weekday()), attendances[-1] if attendances else default_value)

        if self.request_unit_half:
            if self.request_date_from_period == 'am':
                hour_from = float_to_time(attendance_from.hour_from)
                hour_to = float_to_time(attendance_from.hour_to)
            else:
                hour_from = float_to_time(attendance_to.hour_from)
                hour_to = float_to_time(attendance_to.hour_to)
        elif self.request_unit_hours:
            # This hack is related to the definition of the field, basically we convert
            # the negative integer into .5 floats
            hour_from = float_to_time(abs(self.request_hour_from) - 0.5 if self.request_hour_from < 0 else self.request_hour_from)
            hour_to = float_to_time(abs(self.request_hour_to) - 0.5 if self.request_hour_to < 0 else self.request_hour_to)
        elif self.request_unit_custom:
            hour_from = self.date_from.time()
            hour_to = self.date_to.time()
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC'  # custom -> already in UTC
        self.date_from = timezone(tz).localize(datetime.combine(self.request_date_from, hour_from)).astimezone(UTC).replace(tzinfo=None)
        self.date_to = timezone(tz).localize(datetime.combine(self.request_date_to, hour_to)).astimezone(UTC).replace(tzinfo=None)
        self._onchange_leave_dates()
Пример #10
0
    def _set_check_in_out(self):
        signin = signout = False
        self.early_hours = 0.0
        self.late_hours = 0.0
        self.worked_hours = 0.0
        duty_from = self.date + ' ' + str(
            float_to_time(self.duty_time.hour_from))
        duty_to = self.date + ' ' + str(float_to_time(self.duty_time.hour_to))

        duty_from = fields.Datetime.from_string(duty_from)
        duty_to = fields.Datetime.from_string(duty_to)

        self.plan_hours = (duty_to - duty_from).seconds / 3600
        check_in = self.day_log.filtered(lambda log: log.action == 'check_in')
        if check_in:
            signin = min([
                to_naive_user_tz(
                    fields.Datetime.from_string(str(x.action_datetime)),
                    self.env.user) for x in check_in
            ])

            if duty_from > signin:
                self.early_hours = (duty_from - signin).seconds / 3600

            signin = to_naive_utc(signin, self.env.user)
            self.check_in = str(signin)

        check_out = self.day_log.filtered(
            lambda log: log.action == 'check_out')
        if check_out:
            signout = max([
                to_naive_user_tz(
                    fields.Datetime.from_string(str(x.action_datetime)),
                    self.env.user) for x in check_out
            ])

            if signout > duty_to:
                self.late_hours = (signout > duty_to).seconds / 3600

            signout = to_naive_utc(signout, self.env.user)
            self.check_out = str(signout)
        if signin and signout:
            self.worked_hours = (signout - signin).seconds / 3600
Пример #11
0
    def _compute_today_schedule(self):
        public_holidays = self.env["hr.holidays.public"]
        today = fields.Date.today()
        day_date = fields.Date.from_string(today)
        now = fields.Datetime.now()
        for record in self:
            domain = [
                ("date_from", "<=", now),
                ("date_to", ">=", now),
                ("employee_id", "=", record.id),
                ("type", "=", "remove"),
                ("state", "=", "validate"),
            ]
            personal_holidays = self.env["hr.holidays"].search(domain, limit=1)
            if personal_holidays:
                date_from = fields.Date.context_today(
                    self,
                    fields.Datetime.from_string(personal_holidays.date_from),
                )
                record.today_schedule = _(
                    "Absent because of %s since %s" %
                    (personal_holidays.holiday_status_id.name, date_from))
                continue
            if public_holidays.is_public_holiday(today, record.id):
                record.today_schedule = _("Absent today because "
                                          "of public holidays")
                continue

            attendances = record.resource_calendar_id._get_day_attendances(
                day_date, False, False)
            if not attendances:
                record.today_schedule = _("This employee doesn't work today")
            elif len(attendances) == 1:
                record.today_schedule = _("Working from %s to %s") % (
                    float_to_time(attendances.hour_from).strftime("%H:%M"),
                    float_to_time(attendances.hour_to).strftime("%H:%M"),
                )
            else:
                message = record.today_schedule = _("Working from %s to %s") % (
                    float_to_time(attendances[0].hour_from).strftime("%H:%M"),
                    float_to_time(attendances[0].hour_to).strftime("%H:%M"),
                )
                attendances = attendances[1:]
                for att in attendances[:-1]:
                    message = message + _(", from %s to %s") % (
                        float_to_time(att.hour_from).strftime("%H:%M"),
                        float_to_time(att.hour_to).strftime("%H:%M"),
                    )
                record.today_schedule = message + _(" and from %s to %s") % (
                    float_to_time(attendances[-1].hour_from).strftime("%H:%M"),
                    float_to_time(attendances[-1].hour_to).strftime("%H:%M"),
                )
Пример #12
0
    def attendance_action_change(self):
        timez = timezone(self.env.user.tz)
        attendance = self._attendance_action_change()
        if attendance:
            action_time = (fields.Datetime.from_string(
                attendance.check_out
                or attendance.check_in).replace(tzinfo=utc).astimezone(timez))
            work_intervals = self.resource_calendar_id._work_intervals(
                datetime.combine(action_time.date(),
                                 time(0, 0, 0, 0, tzinfo=timez)),
                datetime.combine(action_time.date(),
                                 time(23, 59, 59, 99999, tzinfo=timez)),
                resource=self.resource_id,
            )
            calendar_attendances = self.env["resource.calendar.attendance"]
            for _, _, meta in work_intervals:
                if meta._name == "resource.calendar.attendance":
                    calendar_attendances |= meta

            intervals = []
            for att in calendar_attendances:
                start = timez.localize(
                    datetime.combine(action_time.date(),
                                     float_to_time(att.hour_from)))
                stop = timez.localize(
                    datetime.combine(action_time.date(),
                                     float_to_time(att.hour_to)))
                intervals.append((start, stop, att))

            in_interval = any([
                start + timedelta(minutes=-meta.margin_from or 0) <=
                action_time <= stop + timedelta(minutes=meta.margin_to or 0)
                for start, stop, meta in intervals
            ])
            public_holiday = self.env["hr.holidays.public"].is_public_holiday(
                action_time.date(), self.id)

            if not in_interval or public_holiday:
                date = fields.Date.to_string(action_time.date())
                self._create_warning(date=date, w_type="out_of_interval")
        return attendance
Пример #13
0
    def _get_calendar_leaves(self):
        calendar_leaves = self.env['resource.calendar.leaves']
        self.calendar_leaves_ids = False

        duty_from = self.date + ' ' + str(
            float_to_time(self.duty_time.hour_from))
        duty_to = self.date + ' ' + str(float_to_time(self.duty_time.hour_to))
        c_date = self.date + ' 00:00:00'

        duty_from = fields.Datetime.from_string(duty_from)
        duty_to = fields.Datetime.from_string(duty_to)

        duty_from = to_naive_user_tz(duty_from, self.env.user)
        duty_to = to_naive_user_tz(duty_to, self.env.user)

        date_leaves = calendar_leaves.search([
            ('resource_id', '=', self.employee_id.resource_id.id),
            ('date_from', '<=', str(duty_from)),
            ('date_to', '>', str(duty_from))
        ])

        date_leaves |= calendar_leaves.search([
            ('resource_id', '=', self.employee_id.resource_id.id),
            ('date_from', '<', str(duty_to)), ('date_to', '>=', str(duty_to))
        ])

        date_leaves |= calendar_leaves.search([
            ('resource_id', '=', self.employee_id.resource_id.id),
            ('date_from', '>=', str(duty_from)),
            ('date_to', '<=', str(duty_to))
        ])
        self.calendar_leaves_ids = date_leaves.ids

        absence_type = None
        excuse_seconds = 0
        return absence_type, excuse_seconds
Пример #14
0
    def read_group(self,
                   domain,
                   fields,
                   groupby,
                   offset=0,
                   limit=None,
                   orderby=False,
                   lazy=True):
        res = []
        for data in super(PlanningTemplate,
                          self).read_group(domain, fields, groupby, offset,
                                           limit, orderby, lazy):
            if 'start_time' in data:
                data['start_time'] = float_to_time(
                    data['start_time']).strftime('%H:%M')
            res.append(data)

        return res
Пример #15
0
    def _onchange_request_parameters(self):
        if not self.request_date_from:
            self.date_from = False
            return

        if self.request_unit_half or self.request_unit_hours:
            self.request_date_to = self.request_date_from

        if not self.request_date_to:
            self.date_to = False
            return

        domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id or self.env.user.company_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].search(domain, order='dayofweek, day_period DESC')

        # find first attendance coming after first_day
        attendance_from = next((att for att in attendances if int(att.dayofweek) >= self.request_date_from.weekday()), attendances[0])
        # find last attendance coming before last_day
        attendance_to = next((att for att in reversed(attendances) if int(att.dayofweek) <= self.request_date_to.weekday()), attendances[-1])

        if self.request_unit_half:
            if self.request_date_from_period == 'am':
                hour_from = float_to_time(attendance_from.hour_from)
                hour_to = float_to_time(attendance_from.hour_to)
            else:
                hour_from = float_to_time(attendance_to.hour_from)
                hour_to = float_to_time(attendance_to.hour_to)
        elif self.request_unit_hours:
            hour_from = float_to_time(float(self.request_hour_from))
            hour_to = float_to_time(float(self.request_hour_to))
        elif self.request_unit_custom:
            hour_from = self.date_from.time()
            hour_to = self.date_to.time()
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC'  # custom -> already in UTC
        self.date_from = timezone(tz).localize(datetime.combine(self.request_date_from, hour_from)).astimezone(UTC).replace(tzinfo=None)
        self.date_to = timezone(tz).localize(datetime.combine(self.request_date_to, hour_to)).astimezone(UTC).replace(tzinfo=None)
        self._onchange_leave_dates()
Пример #16
0
    def _onchange_request_parameters(self):
        date_from = False
        date_to = False

        if not self.employee_id:
            return

        if self.request_date_from:
            if self.date_from:
                date_from = fields.Datetime.to_string(
                    datetime.combine(
                        fields.Date.from_string(self.request_date_from),
                        fields.Datetime.from_string(self.date_from).time()))
            else:
                date_from = self.request_date_from

        if self.request_date_to:
            if self.date_to:
                date_to = fields.Datetime.to_string(
                    datetime.combine(
                        fields.Date.from_string(self.request_date_to),
                        fields.Datetime.from_string(self.date_to).time()))
            else:
                date_to = self.request_date_to

        if not self.request_date_from or not self.request_date_to:
            if date_from:
                self.date_from = date_from
            if date_to:
                self.date_to = date_to
            self.number_of_days_temp = 0
            return

        domain = [('calendar_id', '=',
                   self.employee_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].search(
            domain, order='dayofweek, day_period DESC')

        first_day = fields.Date.from_string(date_from)
        last_day = fields.Date.from_string(date_to)

        if self.request_unit_all in ['day', 'half']:
            last_day = first_day

        # find first attendance coming after first_day
        attendance_from = next((att for att in attendances
                                if int(att.dayofweek) >= first_day.weekday()),
                               attendances[0])
        # find last attendance coming before last_day
        attendance_to = next((att for att in reversed(attendances)
                              if int(att.dayofweek) <= last_day.weekday()),
                             attendances[-1])

        if self.request_unit_all == 'day' or (self.request_unit_all == 'period'
                                              and self.leave_type_request_unit
                                              == 'day'):
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        elif self.request_unit_all == 'half':
            hour_from = float_to_time(
                attendance_from.hour_from if self.request_date_from_period ==
                'am' else attendance_to.hour_from)
            hour_to = float_to_time(
                attendance_from.hour_to if self.request_date_from_period ==
                'am' else attendance_to.hour_to)

        elif self.request_unit_all == 'period' and self.leave_type_request_unit == 'half':
            hour_from = float_to_time(
                attendance_from.hour_from if self.request_date_from_period ==
                'am' else attendance_from.hour_to)
            hour_to = float_to_time(
                attendance_to.hour_from if self.request_date_to_period ==
                'am' else attendance_to.hour_to)

        if self.leave_type_request_unit == 'hour' and self.request_unit_all == 'period':
            date_from = fields.Datetime.from_string(date_from)
            date_to = fields.Datetime.from_string(date_to)
        else:
            tz = self.env.user.tz or 'UTC'
            date_from = timezone(tz).localize(
                datetime.combine(first_day, hour_from)).astimezone(UTC)
            date_to = timezone(tz).localize(datetime.combine(
                last_day, hour_to)).astimezone(UTC)

        self.date_from = date_from
        self.date_to = date_to

        if not (self.leave_type_request_unit == 'hour'
                and self.request_unit_all == 'period'):
            date_from = date_from
            date_to = date_to

        self.number_of_days_temp = self._get_number_of_days(
            date_from, date_to, self.employee_id.id)
Пример #17
0
 def compute_and_validate_dates(self, **kwargs):
     date_to = date_from = fields.Datetime
     DummyAttendance = namedtuple(
         'DummyAttendance',
         'hour_from, hour_to, dayofweek, day_period, week_type')
     request_date_from_period = kwargs.get('request_date_from_period')
     request_hour_from = kwargs.get('request_hour_from')
     request_hour_to = kwargs.get('request_hour_to')
     request_date_from = datetime.strptime(kwargs.get('request_date_from'),
                                           "%Y-%m-%d").date()
     if kwargs.get('request_date_to'):
         request_date_to = datetime.strptime(kwargs.get('request_date_to'),
                                             "%Y-%m-%d").date()
     else:
         request_date_to = False
     request_unit_half = False if kwargs.get(
         'request_unit_half') == 'false' else True
     request_unit_hours = False if kwargs.get(
         'request_unit_hours') == 'false' else True
     request_unit_custom = False if kwargs.get(
         'request_unit_custom') == 'false' else True
     number_of_hours_text = kwargs.get('number_of_hours_text')
     employee_id = request.env['hr.employee'].sudo().search([
         ('user_id.id', '=', request.uid)
     ]) or request.env['hr.employee'].sudo().search(
         [('address_home_id', '=', request.env['res.users'].sudo().search(
             [('id', '=', request.uid)]).partner_id.id)])
     number_of_days = 0.0
     number_of_hours = 0
     if request_date_from and request_date_to and \
             request_date_from > request_date_to:
         request_date_to = request_date_from
     if not request_date_from:
         date_from = False
     elif not request_unit_half and not request_unit_hours and not \
             request_date_to:
         date_to = False
     else:
         if request_unit_half or request_unit_hours:
             request_date_to = request_date_from
         company = request.env.company
         resource_calendar_id = employee_id.resource_calendar_id or \
                                company.resource_calendar_id
         domain = [('calendar_id', '=', resource_calendar_id.id),
                   ('display_type', '=', False)]
         attendances = request.env[
             'resource.calendar.attendance'].with_user(
                 SUPERUSER_ID).read_group(domain, [
                     'ids:array_agg(id)', 'hour_from:min(hour_from)',
                     'hour_to:max(hour_to)', 'week_type', 'dayofweek',
                     'day_period'
                 ], ['week_type', 'dayofweek', 'day_period'],
                                          lazy=False)
         attendances = sorted([
             DummyAttendance(group['hour_from'], group['hour_to'],
                             group['dayofweek'], group['day_period'],
                             group['week_type']) for group in attendances
         ],
                              key=lambda att:
                              (att.dayofweek, att.day_period != 'morning'))
         default_value = DummyAttendance(0, 0, 0, 'morning', False)
         if resource_calendar_id.two_weeks_calendar:
             start_week_type = int(
                 math.floor((request_date_from.toordinal() - 1) / 7) % 2)
             attendance_actual_week = [
                 att for att in attendances if att.week_type is False
                 or int(att.week_type) == start_week_type
             ]
             attendance_actual_next_week = [
                 att for att in attendances if att.week_type is False
                 or int(att.week_type) != start_week_type
             ]
             attendance_filtered = [
                 att for att in attendance_actual_week
                 if int(att.dayofweek) >= request_date_from.weekday()
             ]
             attendance_filtered += list(attendance_actual_next_week)
             attendance_filtered += list(attendance_actual_week)
             end_week_type = int(
                 math.floor((request_date_to.toordinal() - 1) / 7) % 2)
             attendance_actual_week = [
                 att for att in attendances if att.week_type is False
                 or int(att.week_type) == end_week_type
             ]
             attendance_actual_next_week = [
                 att for att in attendances if att.week_type is False
                 or int(att.week_type) != end_week_type
             ]
             attendance_filtered_reversed = list(
                 reversed([
                     att for att in attendance_actual_week
                     if int(att.dayofweek) <= request_date_to.weekday()
                 ]))
             attendance_filtered_reversed += list(
                 reversed(attendance_actual_next_week))
             attendance_filtered_reversed += list(
                 reversed(attendance_actual_week))
             attendance_from = attendance_filtered[0]
             attendance_to = attendance_filtered_reversed[0]
         else:
             attendance_from = next(
                 (att for att in attendances
                  if int(att.dayofweek) >= request_date_from.weekday()),
                 attendances[0] if attendances else default_value)
             attendance_to = next(
                 (att for att in reversed(attendances)
                  if int(att.dayofweek) <= request_date_to.weekday()),
                 attendances[-1] if attendances else default_value)
         compensated_request_date_from = request_date_from
         compensated_request_date_to = request_date_to
         if request_unit_half:
             if request_date_from_period == 'am':
                 hour_from = float_to_time(attendance_from.hour_from)
                 hour_to = float_to_time(attendance_from.hour_to)
             else:
                 hour_from = float_to_time(attendance_to.hour_from)
                 hour_to = float_to_time(attendance_to.hour_to)
         elif request_unit_hours:
             hour_from = float_to_time(float(request_hour_from))
             hour_to = float_to_time(float(request_hour_to))
         elif request_unit_custom:
             hour_from = datetime.combine(request_date_from,
                                          datetime.min.time()).time()
             hour_to = datetime.combine(request_date_to,
                                        datetime.max.time()).time()
             user_tz = timezone(
                 request.env.user.tz if request.env.user.tz else 'UTC')
             request_date_from_utc = UTC.localize(
                 datetime.combine(request_date_from, time(
                     0, 0, 0))).astimezone(user_tz).replace(tzinfo=None)
             if request_date_from_utc.date() < request_date_from:
                 compensated_request_date_from = request_date_from + \
                                                 timedelta(days=1)
             elif request_date_from_utc.date() > request_date_from:
                 compensated_request_date_from = request_date_from - \
                                                 timedelta(days=1)
             else:
                 compensated_request_date_from = request_date_from
             request_date_to_utc = UTC.localize(
                 datetime.combine(request_date_to, time(
                     0, 0, 0))).astimezone(user_tz).replace(tzinfo=None)
             if request_date_to_utc.date() < request_date_to:
                 compensated_request_date_to = request_date_to + \
                                               timedelta(days=1)
             elif request_date_to_utc.date() > request_date_to:
                 compensated_request_date_to = request_date_to - \
                                               timedelta(days=1)
             else:
                 compensated_request_date_to = request_date_to
         else:
             hour_from = float_to_time(attendance_from.hour_from)
             hour_to = float_to_time(attendance_to.hour_to)
         date_from = timezone(request.env.user.tz).localize(
             datetime.combine(
                 compensated_request_date_from,
                 hour_from)).astimezone(UTC).replace(tzinfo=None)
         date_to = timezone(request.env.user.tz).localize(
             datetime.combine(compensated_request_date_to,
                              hour_to)).astimezone(UTC).replace(tzinfo=None)
         if request_unit_half:
             result = employee_id._get_work_days_data_batch(
                 date_from, date_to)[employee_id.id]
             result['days'] = 0.5
             number_of_days = result['days']
             number_of_hours = result['hours']
         else:
             company = request.env.company
             today_hours = company.resource_calendar_id.get_work_hours_count(
                 datetime.combine(date_from.date(), time.min),
                 datetime.combine(date_from.date(), time.max), False)
             if request_unit_custom:
                 hours = company.resource_calendar_id.get_work_hours_count(
                     date_from, date_to, False)
                 days = hours / (today_hours or HOURS_PER_DAY)
                 number_of_days = days
                 number_of_hours = hours
             else:
                 number_of_hours = float(kwargs.get('number_of_hours'))
                 number_of_days = number_of_hours / 8
         number_of_hours_text = '%s%g %s%s' % (
             '' if request_unit_half or request_unit_hours else '(',
             float_round(number_of_hours, precision_digits=2), _('Hours'),
             '' if request_unit_half or request_unit_hours else ')')
     hr_leave = request.env['hr.leave'].sudo()
     check_error = {}
     domain = [
         ('date_from', '<', date_to),
         ('date_to', '>', date_from),
         ('employee_id', '=', employee_id.id),
         ('state', 'not in', ['cancel', 'refuse']),
     ]
     number_of_holidays = hr_leave.search_count(domain)
     if number_of_holidays:
         check_error = {
             'checks': "exists",
         }
     holiday_status_id = int(kwargs.get('holiday_status_id'))
     hr_leave_type = request.env['hr.leave.type'].sudo().browse(
         holiday_status_id)
     mapped_days = hr_leave_type.get_employees_days(
         request.env['hr.employee'].sudo().browse(employee_id.id).ids)
     leave_days = mapped_days[employee_id.id][holiday_status_id]
     if hr_leave_type.allocation_type != 'no':
         if request_unit_custom and hr_leave_type.request_unit == 'day':
             if leave_days['virtual_remaining_leaves'] < number_of_days:
                 check_error = {
                     'checks': "over",
                 }
         else:
             if leave_days['virtual_remaining_leaves'] < number_of_hours:
                 check_error = {
                     'checks': "over",
                 }
     date_data = {
         'date_from': date_from,
         'date_to': date_to,
         'number_of_days': number_of_days,
         'number_of_hours': number_of_hours,
         'number_of_hours_text': number_of_hours_text,
         'checks': "",
     }
     date_data.update(check_error)
     return date_data
Пример #18
0
    def _onchange_request_parameters(self):
        date_from = False
        date_to = False

        if not self.employee_id:
            return

        if self.request_date_from:
            if self.date_from:
                date_from = fields.Datetime.to_string(datetime.combine(fields.Date.from_string(self.request_date_from), fields.Datetime.from_string(self.date_from).time()))
            else:
                date_from = datetime.combine(self.request_date_from, time.min)

        if self.request_date_to:
            if self.date_to:
                date_to = fields.Datetime.to_string(datetime.combine(fields.Date.from_string(self.request_date_to), fields.Datetime.from_string(self.date_to).time()))
            else:
                date_to = datetime.combine(self.request_date_to, time.max)

        if not self.request_date_from or not self.request_date_to:
            if date_from:
                self.date_from = date_from
            if date_to:
                self.date_to = date_to
            self.number_of_days_temp = 0
            return

        domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].search(domain, order='dayofweek, day_period DESC')

        first_day = fields.Date.from_string(date_from)
        last_day = fields.Date.from_string(date_to)

        if self.request_unit_all in ['day', 'half']:
            last_day = first_day

        # find first attendance coming after first_day
        attendance_from = next((att for att in attendances if int(att.dayofweek) >= first_day.weekday()), attendances[0])
        # find last attendance coming before last_day
        attendance_to = next((att for att in reversed(attendances) if int(att.dayofweek) <= last_day.weekday()), attendances[-1])

        if self.request_unit_all == 'day' or (self.request_unit_all == 'period' and self.leave_type_request_unit == 'day'):
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        elif self.request_unit_all == 'half':
            hour_from = float_to_time(attendance_from.hour_from if self.request_date_from_period == 'am' else attendance_to.hour_from)
            hour_to = float_to_time(attendance_from.hour_to if self.request_date_from_period == 'am' else attendance_to.hour_to)

        elif self.request_unit_all == 'period' and self.leave_type_request_unit == 'half':
            hour_from = float_to_time(attendance_from.hour_from if self.request_date_from_period == 'am' else attendance_from.hour_to)
            hour_to = float_to_time(attendance_to.hour_from if self.request_date_to_period == 'am' else attendance_to.hour_to)

        if self.leave_type_request_unit == 'hour' and self.request_unit_all == 'period':
            date_from = fields.Datetime.from_string(date_from)
            date_to = fields.Datetime.from_string(date_to)
        else:
            tz = self.env.user.tz or 'UTC'
            date_from = timezone(tz).localize(datetime.combine(first_day, hour_from)).astimezone(UTC)
            date_to = timezone(tz).localize(datetime.combine(last_day, hour_to)).astimezone(UTC)

        self.date_from = date_from
        self.date_to = date_to

        if not (self.leave_type_request_unit == 'hour' and self.request_unit_all == 'period'):
            date_from = date_from
            date_to = date_to

        self.number_of_days_temp = self._get_number_of_days(date_from, date_to, self.employee_id.id)
Пример #19
0
    def _onchange_request_parameters(self):
        if not self.request_date_from:
            self.date_from = False
            return

        if self.request_unit_half or self.request_unit_hours:
            self.request_date_to = self.request_date_from

        if not self.request_date_to:
            self.date_to = False
            return

        resource_calendar_id = self.employee_id.resource_calendar_id or self.env.company.resource_calendar_id
        domain = [('calendar_id', '=', resource_calendar_id.id), ('display_type', '=', False)]
        attendances = self.env['resource.calendar.attendance'].search(domain, order='dayofweek, day_period DESC')

        if resource_calendar_id.two_weeks_calendar:
            # find week type of start_date
            start_week_type = int(math.floor((self.request_date_from.toordinal() - 1) / 7) % 2)
            attendance_actual_week = attendances.filtered(lambda att: att.week_type is False or int(att.week_type) == start_week_type)
            attendance_actual_next_week = attendances.filtered(lambda att: att.week_type is False or int(att.week_type) != start_week_type)
            # First, add days of actual week coming after date_from
            attendance_filtred = list(attendance_actual_week.filtered(lambda att: int(att.dayofweek) >= self.request_date_from.weekday()))
            # Second, add days of the other type of week
            attendance_filtred += list(attendance_actual_next_week)
            # Third, add days of actual week (to consider days that we have remove first because they coming before date_from)
            attendance_filtred += list(attendance_actual_week)

            end_week_type = int(math.floor((self.request_date_to.toordinal() - 1) / 7) % 2)
            attendance_actual_week = attendances.filtered(lambda att: att.week_type is False or int(att.week_type) == end_week_type)
            attendance_actual_next_week = attendances.filtered(lambda att: att.week_type is False or int(att.week_type) != end_week_type)
            attendance_filtred_reversed = list(reversed(attendance_actual_week.filtered(lambda att: int(att.dayofweek) <= self.request_date_to.weekday())))
            attendance_filtred_reversed += list(reversed(attendance_actual_next_week))
            attendance_filtred_reversed += list(reversed(attendance_actual_week))

            # find first attendance coming after first_day
            attendance_from = attendance_filtred[0]
            # find last attendance coming before last_day
            attendance_to = attendance_filtred_reversed[0]
        else:
            # find first attendance coming after first_day
            attendance_from = next((att for att in attendances if int(att.dayofweek) >= self.request_date_from.weekday()), attendances[0])
            # find last attendance coming before last_day
            attendance_to = next((att for att in reversed(attendances) if int(att.dayofweek) <= self.request_date_to.weekday()), attendances[-1])

        if self.request_unit_half:
            if self.request_date_from_period == 'am':
                hour_from = float_to_time(attendance_from.hour_from)
                hour_to = float_to_time(attendance_from.hour_to)
            else:
                hour_from = float_to_time(attendance_to.hour_from)
                hour_to = float_to_time(attendance_to.hour_to)
        elif self.request_unit_hours:
            hour_from = float_to_time(float(self.request_hour_from))
            hour_to = float_to_time(float(self.request_hour_to))
        elif self.request_unit_custom:
            hour_from = self.date_from.time()
            hour_to = self.date_to.time()
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC'  # custom -> already in UTC
        self.date_from = timezone(tz).localize(datetime.combine(self.request_date_from, hour_from)).astimezone(UTC).replace(tzinfo=None)
        self.date_to = timezone(tz).localize(datetime.combine(self.request_date_to, hour_to)).astimezone(UTC).replace(tzinfo=None)
        self._onchange_leave_dates()
Пример #20
0
    def _onchange_request_parameters(self):
        if not self.request_date_from:
            self.date_from = False
            return

        if self.request_unit_half or self.request_unit_hours:
            print()
            # comment below line because when we select half day it change the to date
        #             self.request_date_to = self.request_date_from

        if not self.request_date_to:
            self.date_to = False
            return

        #         roster_id = self.env['hr.attendance.roster'].search([('employee_id','=',self.employee_id.id),('date','=',self.date_from.date())],limit=1)
        #         # print("-------------roster_id", roster_id)
        #         if roster_id and roster_id.shift_id:
        #             if roster_id.shift_id.night_shift:
        #                 self.night_shift = True
        #             else:
        #                 self.night_shift = False
        #             domain =[('calendar_id', '=',roster_id.shift_id.id)]
        #         else:
        #             if self.employee_id.resource_calendar_id.night_shift or self.env.user.company_id.resource_calendar_id.night_shift:
        #                 self.night_shift = True
        #             else:
        #                 self.night_shift = False
        domain = [('calendar_id', '=',
                   self.employee_id.resource_calendar_id.id or self.env.user.company_id.resource_calendar_id.id)]
        attendances = self.env['resource.calendar.attendance'].search(domain, order='dayofweek, day_period DESC')

        # find first attendance coming after first_day
        attendance_from = next((att for att in attendances if int(att.dayofweek) >= self.request_date_from.weekday()),
                               attendances[0])
        # find last attendance coming before last_day
        attendance_to = next(
            (att for att in reversed(attendances) if int(att.dayofweek) <= self.request_date_to.weekday()),
            attendances[-1])

        if self.request_unit_half:
            if self.request_date_from_period == 'am':
                hour_from = float_to_time(attendance_from.hour_from)
                # print("hour_fromhour_fromhour_fromhour_from",hour_from)
                hour_to = float_to_time(attendance_from.hour_to)
                # print("???????//hour_fromhour_fromhour_from",hour_to)
            else:
                hour_from = float_to_time(attendance_to.hour_from)
                hour_to = float_to_time(attendance_to.hour_to)

        elif self.request_unit_hours:
            # This hack is related to the definition of the field, basically we convert
            # the negative integer into .5 floats
            hour_from = float_to_time(
                abs(self.request_hour_from) - 0.5 if self.request_hour_from < 0 else self.request_hour_from)
            #             print("111111111111111111111111111111111",hour_from)
            hour_to = float_to_time(
                abs(self.request_hour_to) - 0.5 if self.request_hour_to < 0 else self.request_hour_to)
        #             print("22222222222222222222222222222",hour_to)
        elif self.request_unit_custom:
            hour_from = self.date_from.time()
            hour_to = self.date_to.time()
        else:
            hour_from = float_to_time(attendance_from.hour_from)
            hour_to = float_to_time(attendance_to.hour_to)

        tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC'  # custom -> already in UTC
        self.date_from = timezone(tz).localize(datetime.combine(self.request_date_from, hour_from)).astimezone(
            UTC).replace(tzinfo=None)
        self.date_to = timezone(tz).localize(datetime.combine(self.request_date_to, hour_to)).astimezone(UTC).replace(
            tzinfo=None)
Пример #21
0
    def _get_attendance_log(self):
        self.day_log = False
        att_log = self.env['hr.attendance.log']
        start_date = self.date + ' 00:00:00'
        end_date = self.date + ' 23:59:59'
        attendance_log_ids = att_log.search([
            ('employee_id', '=', self.employee_id.id),
            ('action_datetime', '>=', start_date),
            ('action_datetime', '<=', end_date),
            ('state', 'in', ['approved', 'fetched'])
        ])

        attendances = self._get_attendances(self.employee_id, self.date)
        attendances_recs = self.search([('date', '=', self.date),
                                        ('duty_time', 'in', attendances.ids)])

        morning_duty = attendances_recs.filtered(
            lambda x: x.duty_time.shift == 'morning')
        evening_duty = attendances_recs.filtered(
            lambda x: x.duty_time.shift == 'evening')

        if morning_duty:
            morning_duty = morning_duty[0] or False
            shift_from = self.date + ' ' + str(
                float_to_time(morning_duty.duty_time.hour_from))
            shift_to = self.date + ' ' + str(
                float_to_time(morning_duty.duty_time.hour_to))

            shift_from = fields.Datetime.from_string(shift_from)
            shift_to = fields.Datetime.from_string(shift_to)

            if not evening_duty:
                morning_signs = attendance_log_ids
            if evening_duty:
                evening_shift_from = self.date + ' ' + str(
                    float_to_time(evening_duty[0].duty_time.hour_from))
                evening_shift_from = fields.Datetime.from_string(
                    evening_shift_from)

                morning_signs = attendance_log_ids.filtered(
                    lambda x: to_naive_user_tz(
                        fields.Datetime.from_string(x.action_datetime), self.
                        env.user) <= shift_to or (to_naive_user_tz(
                            fields.Datetime.from_string(x.action_datetime),
                            self.env.user) < evening_shift_from and x.action ==
                                                  'check_out'))
            morning_signs.write({'attendance_id': morning_duty.id})
        if evening_duty:
            evening_duty = evening_duty[0] or False
            shift_from = self.date + ' ' + str(
                float_to_time(evening_duty.duty_time.hour_from))
            shift_to = self.date + ' ' + str(
                float_to_time(evening_duty.duty_time.hour_to))

            shift_from = fields.Datetime.from_string(shift_from)
            shift_to = fields.Datetime.from_string(shift_to)

            if not morning_duty:
                evening_signs = attendance_log_ids

            if morning_duty:
                morning_shift_to = self.date + ' ' + str(
                    float_to_time(morning_duty[0].duty_time.hour_to))
                morning_shift_to = fields.Datetime.from_string(
                    morning_shift_to)

                evening_signs = attendance_log_ids.filtered(
                    lambda x: to_naive_user_tz(
                        fields.Datetime.from_string(x.action_datetime), self.
                        env.user) >= shift_from or (to_naive_user_tz(
                            fields.Datetime.from_string(x.action_datetime),
                            self.env.user) > morning_shift_to and x.action ==
                                                    'chech_in'))
            evening_signs.write({'attendance_id': evening_duty.id})

        return True
Пример #22
0
    def _get_late(self):
        signin = signout = False
        duty_from = self.date + ' ' + str(
            float_to_time(self.duty_time.hour_from))
        duty_to = self.date + ' ' + str(float_to_time(self.duty_time.hour_to))

        duty_from = fields.Datetime.from_string(duty_from)
        duty_to = fields.Datetime.from_string(duty_to)

        excuse = float_to_time(self.duty_time.calendar_id.excuse)
        excuse = excuse.hour * 3600 + excuse.minute * 60 + excuse.second

        max_late = float_to_time(self.duty_time.calendar_id.max_late)
        max_late = max_late.hour * 3600 + max_late.minute * 60 + max_late.second

        if self.check_in:
            signin = self.check_in
            signin = fields.Datetime.from_string(signin)
            signin = to_naive_user_tz(signin, self.env.user)

        if self.check_out:
            signout = self.check_out
            signout = fields.Datetime.from_string(signout)
            signout = to_naive_user_tz(signout, self.env.user)

        leaves_duration = self._get_leaves_durations()

        absence_type = False
        late = 0.0
        diff_from_duety = 0.0
        leave_signin = False
        leave_signout = False

        #there is at least one leave
        if leaves_duration:
            (leave_signin,
             leave_signout), temp_absence_type = leaves_duration.popitem()
            if not signin or leave_signin < signin:
                signin = leave_signin
            if not signout or leave_signout > signout:
                signout = leave_signout

        if not signin or not signout:
            self.absence_type = 'absent'
            self.total_delay = (duty_to - duty_from).seconds / 3600.0
            self.diff_from_duety = (duty_to - duty_from).seconds / 3600.0
            return

        delta = 0.0
        if signin > duty_from:
            delta += (signin - duty_from).seconds
        if duty_to > signout:
            delta += (duty_to - signout).seconds

        if delta > excuse:
            diff_from_duety = delta - excuse
            if diff_from_duety > max_late:
                self.absence_type = 'absent'
                self.total_delay = (duty_to - duty_from).seconds / 3600.0
                self.diff_from_duety = (duty_to - duty_from).seconds / 3600.0
                return

        if not absence_type:
            if delta == 0:
                absence_type = 'no_delay'
            if delta > 0:
                absence_type = 'delay'

        self.absence_type = absence_type
        self.total_delay = delta / 3600.0
        self.diff_from_duety = diff_from_duety / 3600.0
        return
Пример #23
0
    def _get_leaves_durations(self):
        duty_from = self.date + ' ' + str(
            float_to_time(self.duty_time.hour_from))
        duty_to = self.date + ' ' + str(float_to_time(self.duty_time.hour_to))

        duty_from = fields.Datetime.from_string(duty_from)
        duty_to = fields.Datetime.from_string(duty_to)

        date_leaves_dicts = {}
        date_leaves = self.calendar_leaves_ids.filtered(
            lambda x: to_naive_user_tz(
                fields.Datetime.from_string(x.date_from), self.env.user
            ) <= duty_from and to_naive_user_tz(
                fields.Datetime.from_string(x.date_to), self.env.user
            ) >= duty_to)
        date_leaves_dicts.update({(duty_from, duty_to): x.type
                                  for x in date_leaves})

        date_leaves = self.calendar_leaves_ids.filtered(
            lambda x: to_naive_user_tz(
                fields.Datetime.from_string(x.date_from), self.env.user
            ) <= duty_from and to_naive_user_tz(
                fields.Datetime.from_string(x.date_to), self.env.user
            ) < duty_to)
        date_leaves_dicts.update({
            (duty_from,
             to_naive_user_tz(fields.Datetime.from_string(x.date_to),
                              self.env.user)): x.type
            for x in date_leaves
        })

        date_leaves = self.calendar_leaves_ids.filtered(
            lambda x: to_naive_user_tz(
                fields.Datetime.from_string(x.date_from), self.env.user
            ) > duty_from and to_naive_user_tz(
                fields.Datetime.from_string(x.date_to), self.env.user
            ) < duty_to)
        date_leaves_dicts.update({
            (to_naive_user_tz(fields.Datetime.from_string(x.date_from),
                              self.env.user),
             to_naive_user_tz(fields.Datetime.from_string(x.date_to),
                              self.env.user)): x.type
            for x in date_leaves
        })

        date_leaves = self.calendar_leaves_ids.filtered(
            lambda x: to_naive_user_tz(
                fields.Datetime.from_string(x.date_from), self.env.user
            ) > duty_from and to_naive_user_tz(
                fields.Datetime.from_string(x.date_to), self.env.user
            ) > duty_to)
        date_leaves_dicts.update({
            (to_naive_user_tz(fields.Datetime.from_string(x.date_from),
                              self.env.user), duty_to): x.type
            for x in date_leaves
        })

        if date_leaves_dicts:
            #get the leave with the most duration
            keys = date_leaves_dicts.keys()
            keys = {(x[1] - x[0]).seconds: x for x in keys}

            #get the max key using diffrence
            max_key = max(keys.keys())

            #get the max key using keys dict
            max_key = keys[max_key]

            #get the max key using date_leaves_dicts dict
            return {max_key: date_leaves_dicts[max_key]}

        return {}