Example #1
0
    def _get_car_atn(self, acquisition_date, car_value, fuel_type, co2):
        # Compute the correction coefficient from the age of the car
        now = Datetime.from_string(Datetime.now())
        start = Datetime.from_string(acquisition_date)
        if start:
            number_of_month = (now.year - start.year) * 12.0 + now.month - start.month + int(bool(now.day - start.day + 1))
            if number_of_month <= 12:
                age_coefficient = 1.00
            elif number_of_month <= 24:
                age_coefficient = 0.94
            elif number_of_month <= 36:
                age_coefficient = 0.88
            elif number_of_month <= 48:
                age_coefficient = 0.82
            elif number_of_month <= 60:
                age_coefficient = 0.76
            else:
                age_coefficient = 0.70
            car_value = car_value * age_coefficient
            # Compute atn value from corrected car_value
            magic_coeff = 6.0 / 7.0  # Don't ask me why
            if fuel_type == 'electric':
                atn = 0.0
            else:
                if fuel_type in ['diesel', 'hybrid']:
                    reference = 87.0
                else:
                    reference = 105.0

                if co2 <= reference:
                    atn = car_value * max(0.04, (0.055 - 0.001 * (reference - co2))) * magic_coeff
                else:
                    atn = car_value * min(0.18, (0.055 + 0.001 * (co2 - reference))) * magic_coeff
            return max(1280, atn) / 12.0
Example #2
0
    def test_50_calendar_schedule_days(self):
        """ Testing calendar days scheduling """

        # --------------------------------------------------
        # Test1: with calendar
        # --------------------------------------------------

        res = self.calendar.schedule_days_get_date(5, day_date=self.date1)
        self.assertEqual(
            res.date(), Datetime.from_string("2013-02-26 00:00:00").date(), "resource_calendar: wrong days scheduling"
        )
        res = self.calendar.schedule_days_get_date(-2, day_date=self.date1)
        self.assertEqual(
            res.date(), Datetime.from_string("2013-02-08 00:00:00").date(), "resource_calendar: wrong days scheduling"
        )

        res = self.calendar.schedule_days_get_date(
            5, day_date=self.date1, compute_leaves=True, resource_id=self.resource1_id
        )
        self.assertEqual(
            res.date(), Datetime.from_string("2013-03-01 00:00:00").date(), "resource_calendar: wrong days scheduling"
        )

        # --------------------------------------------------
        # Test2: misc
        # --------------------------------------------------

        # Without calendar, should only count days -> 12 -> 16, 5 days with default intervals
        res = self.ResourceCalendar.with_context(self.context).schedule_days_get_date(
            5, day_date=self.date1, default_interval=(8, 16)
        )
        self.assertEqual(res, Datetime.from_string("2013-02-16 16:00:00"), "resource_calendar: wrong days scheduling")
Example #3
0
    def test_calendar_working_day_intervals_limited_attendances(self):
        """ Test attendances limited in time. """
        attendance = self.env['resource.calendar.attendance'].search(
            [('name', '=', 'Att3')])
        attendance.write({
            'date_from': self.date2 + relativedelta(days=7),
            'date_to': False,
        })
        intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date2)
        self.assertEqual(intervals, [(Datetime.from_string('2013-02-15 10:11:12'), Datetime.from_string('2013-02-15 13:00:00'))])

        attendance.write({
            'date_from': False,
            'date_to': self.date2 - relativedelta(days=7),
        })
        intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date2)
        self.assertEqual(intervals, [(Datetime.from_string('2013-02-15 10:11:12'), Datetime.from_string('2013-02-15 13:00:00'))])

        attendance.write({
            'date_from': self.date2 + relativedelta(days=7),
            'date_to': self.date2 - relativedelta(days=7),
        })
        intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date2)
        self.assertEqual(intervals, [(Datetime.from_string('2013-02-15 10:11:12'), Datetime.from_string('2013-02-15 13:00:00'))])

        attendance.write({
            'date_from': self.date2,
            'date_to': self.date2,
        })
        intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date2)
        self.assertEqual(len(intervals), 2)
        self.assertEqual(intervals[0], (Datetime.from_string('2013-02-15 10:11:12'), Datetime.from_string('2013-02-15 13:00:00')))
        self.assertEqual(intervals[1], (Datetime.from_string('2013-02-15 16:00:00'), Datetime.from_string('2013-02-15 23:00:00')))
Example #4
0
 def test_calendar_hours_scheduling_timezone(self):
     # user in timezone UTC-9 asks for work hours
     self.env.user.tz = 'US/Alaska'
     res = self.calendar.plan_hours(
         42,
         to_naive_utc(Datetime.from_string('2013-02-12 09:25:00'), self.env.user))
     self.assertEqual(res, to_naive_utc(Datetime.from_string('2013-02-26 11:25:00'), self.env.user))
Example #5
0
 def test_interval_schedule_hours(self):
     cleaned_intervals = self.env['resource.calendar'].interval_clean(self.intervals)
     result = self.env['resource.calendar'].interval_schedule_hours(cleaned_intervals, 5.5)
     self.assertEqual(len(result), 2)
     # First interval: 03, 8-10 untouched
     self.assertEqual(result[0], (Datetime.from_string('2013-02-03 08:00:00'), Datetime.from_string('2013-02-03 10:00:00')))
     # First interval: 04, 08-11:30
     self.assertEqual(result[1], (Datetime.from_string('2013-02-04 08:00:00'), Datetime.from_string('2013-02-04 11:30:00')))
Example #6
0
 def test_calendar_working_hours_default_calendar(self):
     # Test without calendar and default_interval
     res = self.env['resource.calendar'].with_context(tz='UTC').get_working_hours(
         Datetime.from_string('2013-02-12 06:00:00'),
         Datetime.from_string('2013-02-15 23:00:00'),
         compute_leaves=True, resource_id=self.resource1_id,
         default_interval=(8, 16))
     self.assertEqual(res, 32.0)
Example #7
0
 def test_interval_schedule_hours_backwards(self):
     cleaned_intervals = self.env['resource.calendar']._interval_merge(self.intervals)
     result = self.env['resource.calendar']._interval_schedule_hours(cleaned_intervals, 5.5, backwards=True)
     self.assertEqual(len(result), 2)
     # First interval: 03, 8-10 untouched
     self.assertEqual(result[1][:2], (Datetime.from_string('2013-02-04 17:00:00'), Datetime.from_string('2013-02-04 21:00:00')))
     # First interval: 04, 08-11:30
     self.assertEqual(result[0][:2], (Datetime.from_string('2013-02-04 12:30:00'), Datetime.from_string('2013-02-04 14:00:00')))
Example #8
0
 def test_calendar_working_hours(self):
     # new API: resource without leaves
     # res: 2 weeks -> 40 hours
     res = self.calendar.get_work_hours_count(
         Datetime.from_string('2013-02-12 06:00:00'),
         Datetime.from_string('2013-02-22 23:00:00'),
         self.resource1_id,
         compute_leaves=False)
     self.assertEqual(res, 40.0)
Example #9
0
 def test_calendar_working_hours_leaves(self):
     # new API: resource and leaves
     # res: 2 weeks -> 40 hours - (3+4) leave hours
     res = self.calendar.get_work_hours_count(
         Datetime.from_string('2013-02-12 06:00:00'),
         Datetime.from_string('2013-02-22 23:00:00'),
         self.resource1_id,
         compute_leaves=True)
     self.assertEqual(res, 33.0)
Example #10
0
 def test_interval_schedule_hours_backwards(self):
     cleaned_intervals = self.env['resource.calendar'].interval_clean(self.intervals)
     cleaned_intervals.reverse()
     result = self.env['resource.calendar'].interval_schedule_hours(cleaned_intervals, 5.5, remove_at_end=False)
     self.assertEqual(len(result), 2)
     # First interval: 03, 8-10 untouched
     self.assertEqual(result[0], (Datetime.from_string('2013-02-04 17:00:00'), Datetime.from_string('2013-02-04 21:00:00')))
     # First interval: 04, 08-11:30
     self.assertEqual(result[1], (Datetime.from_string('2013-02-04 12:30:00'), Datetime.from_string('2013-02-04 14:00:00')))
Example #11
0
 def test_interval_merge(self):
     cleaned_intervals = self.env['resource.calendar']._interval_merge(self.intervals)
     self.assertEqual(len(cleaned_intervals), 3)
     # First interval: 03, unchanged
     self.assertEqual(cleaned_intervals[0][:2], (Datetime.from_string('2013-02-03 08:00:00'), Datetime.from_string('2013-02-03 10:00:00')))
     # Second interval: 04, 08-14, combining 08-12 and 11-14, 09-11 being inside 08-12
     self.assertEqual(cleaned_intervals[1][:2], (Datetime.from_string('2013-02-04 08:00:00'), Datetime.from_string('2013-02-04 14:00:00')))
     # Third interval: 04, 17-21, 18-19 being inside 17-21
     self.assertEqual(cleaned_intervals[2][:2], (Datetime.from_string('2013-02-04 17:00:00'), Datetime.from_string('2013-02-04 21:00:00')))
Example #12
0
    def test_30_calendar_working_days(self):
        """ Testing calendar hours computation on a working day """

        # Test: day1, beginning at 10:30 -> work from 10:30 (arrival) until 16:00
        intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date1.replace(hour=10, minute=30, second=0))
        self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-12 10:30:00'), 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-12 16:00:00'), 'resource_calendar: wrong working interval / day computing')
        # Test: hour computation for same interval, should give 5.5
        wh = self.calendar.get_working_hours_of_date(start_dt=self.date1.replace(hour=10, minute=30, second=0))
        self.assertEqual(wh, 5.5, 'resource_calendar: wrong working interval / day time computing')

        # Test: day1+7 on leave, without leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7)
        )
        # Result: day1 (08->16)
        self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval/day computing')
        self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-19 08:00:00'), 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-19 16:00:00'), 'resource_calendar: wrong working interval / day computing')

        # Test: day1+7 on leave, with generic leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7),
            compute_leaves=True
        )
        # Result: day1 (08->09 + 12->16)
        self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working interval/day computing')
        self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-19 08:00:00'), 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-19 09:00:00'), 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[1][0], Datetime.from_string('2013-02-19 12:00:00'), 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[1][1], Datetime.from_string('2013-02-19 16:00:00'), 'resource_calendar: wrong working interval / day computing')

        # Test: day1+14 on leave, with generic leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=14),
            compute_leaves=True
        )
        # Result: day1 (08->16)
        self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval/day computing')
        self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-26 08:00:00'), 'resource_calendar: wrong working interval / day computing')
        self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-26 16:00:00'), 'resource_calendar: wrong working interval / day computing')

        # Test: day1+14 on leave, with resource leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=14),
            compute_leaves=True,
            resource_id=self.resource1_id
        )
        # Result: nothing, because on leave
        self.assertEqual(len(intervals), 0, 'resource_calendar: wrong working interval/day computing')
Example #13
0
    def test_leave(self):
        def to_tuple(interval):
            return (interval.start_datetime, interval.end_datetime)

        # Here we test if the leaves are correctly computed in the case our user is in UTC
        # NB: Beware of winter/spring time
        work_no_tz = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-12-25'), time(0), time(23, 59, 59), self.resource1_id)]
        self.assertEqual(work_no_tz[0], (Datetime.from_string('2018-12-25 08:00:00'), Datetime.from_string('2018-12-25 16:00:00')))

        work_user_tz = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-05-01'), time(0), time(23, 59, 59), self.resource1_id)]
        self.assertEqual(work_user_tz[0], (Datetime.from_string('2018-05-01 08:00:00'), Datetime.from_string('2018-05-01 16:00:00')))

        work_spec = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-04-06'), time(0), time(23, 59, 59), self.resource1_id)]
        self.assertEqual(work_spec[0], (Datetime.from_string('2018-04-06 08:00:00'), Datetime.from_string('2018-04-06 13:00:00')))
Example #14
0
    def test_work_days_count(self):
        # user in timezone UTC-9 asks for work hours
        self.env.user.tz = 'US/Alaska'

        res = self.test.get_work_days_count(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-22 23:00:00'), self.env.user))
        self.assertEqual(res, 3.75)  # generic leaves, 3 hours

        res = self.test.get_work_days_count(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-22 20:00:00'), self.env.user))
        self.assertEqual(res, 3.5)  # last day is truncated of 3 hours on 12)

        self.env['resource.calendar.leaves'].create({
            'name': 'Timezoned Leaves',
            'calendar_id': self.test.resource_calendar_id.id,
            'resource_id': self.test.resource_id.id,
            'date_from': to_naive_utc(Datetime.from_string('2013-02-13 10:00:00'), self.env.user),
            'date_to': to_naive_utc(Datetime.from_string('2013-02-17 12:00:00'), self.env.user)
        })

        res = self.test.get_work_days_count(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-22 20:00:00'), self.env.user))
        self.assertEqual(res, 2.5)  # one day is on leave and last day is truncated of 3 hours on 12)
Example #15
0
    def test_calendar_working_hours_leaves(self):
        # old API: resource and leaves
        # res: 2 weeks -> 40 hours - (3+4) leave hours
        res = self.calendar._interval_hours_get(
            Datetime.from_string('2013-02-12 06:00:00'),
            Datetime.from_string('2013-02-22 23:00:00'),
            resource_id=self.resource1_id, exclude_leaves=False)
        self.assertEqual(res, 33.0)

        # new API: resource and leaves
        # res: 2 weeks -> 40 hours - (3+4) leave hours
        res = self.calendar.get_working_hours(
            Datetime.from_string('2013-02-12 06:00:00'),
            Datetime.from_string('2013-02-22 23:00:00'),
            compute_leaves=True, resource_id=self.resource1_id)
        self.assertEqual(res, 33.0)
Example #16
0
 def test_calendar_hours_scheduling_timezone_2(self):
     # Call schedule_hours for a user in Autralia, Sydney (GMT+10)
     # Two cases:
     # - start at 2013-02-15 08:00:00 => 2013-02-14 21:00:00 in UTC
     # - start at 2013-02-15 11:00:00 => 2013-02-15 00:00:00 in UTC
     self.env.user.tz = 'Australia/Sydney'
     self.env['resource.calendar.attendance'].create({
         'name': 'Day3 - 1',
         'dayofweek': '3',
         'hour_from': 8,
         'hour_to': 12,
         'calendar_id': self.calendar.id,
     })
     self.env['resource.calendar.attendance'].create({
         'name': 'Day3 - 2',
         'dayofweek': '3',
         'hour_from': 13,
         'hour_to': 17,
         'calendar_id': self.calendar.id,
     })
     hours = 1.0/60.0
     for test_date in ['2013-02-15 08:00:00', '2013-02-15 11:00:00']:
         start_dt = Datetime.from_string(test_date)
         start_dt_utc = to_naive_utc(start_dt, self.env.user)
         res = self.calendar._schedule_hours(hours, start_dt_utc)
         self.assertEqual(
             [(start_dt_utc, start_dt_utc.replace(minute=1))], res,
             'resource_calendar: wrong schedule_hours computation')
Example #17
0
 def _check_session_timing(self):
     self.ensure_one()
     date_today = datetime.utcnow()
     session_start = Datetime.from_string(self.start_at)
     if not date_today - timedelta(hours=24) <= session_start:
         raise UserError(_("This session has been opened another day. To comply with the French law, you should close sessions on a daily basis. Please close session %s and open a new one.") % self.name)
     return True
Example #18
0
 def _get_acquisition_date(self):
     self.ensure_one()
     return babel.dates.format_date(
         date=Datetime.from_string(self.acquisition_date),
         format='MMMM y',
         locale=self._context.get('lang') or 'en_US'
     )
Example #19
0
    def test_leaves_timezones(self):
        self.env.user.tz = 'US/Alaska' # UTC-9

        def to_tuple(interval):
            return (interval.start_datetime, interval.end_datetime)

        # Here we test if the leaves are correctly computed in the case our user is in tz Alaska
        # NB: Beware of winter/spring time
        work_no_tz = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-12-25'), time(0), time(23, 59, 59), self.resource1_id)]
        self.assertEqual(work_no_tz[0], (Datetime.from_string('2018-12-25 17:00:00'), Datetime.from_string('2018-12-26 01:00:00')))

        work_user_tz = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-05-01'), time(0), time(23, 59, 59), self.resource1_id)]
        self.assertEqual(work_user_tz[0], (Datetime.from_string('2018-05-01 16:00:00'), Datetime.from_string('2018-05-02 00:00:00')))

        work_spec = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-04-06'), time(0), time(23, 59, 59), self.resource1_id)]
        self.assertEqual(work_spec[0], (Datetime.from_string('2018-04-06 16:00:00'), Datetime.from_string('2018-04-06 21:00:00')))
Example #20
0
    def test_calendar_working_day_intervals_leaves_generic(self):
        # Test: day0 with leaves outside range: 1 interval
        intervals = self.calendar.get_working_intervals_of_day(start_dt=Datetime.from_string('2013-02-12 07:00:00'), compute_leaves=True)
        self.assertEqual(len(intervals), 1)
        self.assertEqual(intervals[0], (Datetime.from_string('2013-02-12 08:00:00'), Datetime.from_string('2013-02-12 16:00:00')))

        # Test: day0 with leaves: 2 intervals because of leave between 9 ans 12, ending at 15:45:30
        intervals = self.calendar.get_working_intervals_of_day(start_dt=Datetime.from_string('2013-02-19 08:15:00'),
                                                               end_dt=Datetime.from_string('2013-02-19 15:45:30'),
                                                               compute_leaves=True)
        self.assertEqual(len(intervals), 2)
        self.assertEqual(intervals[0], (Datetime.from_string('2013-02-19 08:15:00'), Datetime.from_string('2013-02-19 09:00:00')))
        self.assertEqual(intervals[1], (Datetime.from_string('2013-02-19 12:00:00'), Datetime.from_string('2013-02-19 15:45:30')))
Example #21
0
    def test_calendar_working_day_intervals_leaves_generic(self):
        # Test: day0 with leaves outside range: 1 interval
        intervals = self.calendar._get_day_work_intervals(Date.from_string('2013-02-12'), start_time=time(7, 0, 0), compute_leaves=True)
        self.assertEqual(len(intervals), 1)
        self.assertEqual(intervals[0][:2], (Datetime.from_string('2013-02-12 08:00:00'), Datetime.from_string('2013-02-12 16:00:00')))

        # Test: day0 with leaves: 2 intervals because of leave between 9 and 12, ending at 15:45:30
        intervals = self.calendar._get_day_work_intervals(Date.from_string('2013-02-19'),
                                                          start_time=time(8, 15, 0),
                                                          end_time=time(15, 45, 30),
                                                          compute_leaves=True)
        self.assertEqual(len(intervals), 2)
        self.assertEqual(intervals[0][:2], (Datetime.from_string('2013-02-19 08:15:00'), Datetime.from_string('2013-02-19 09:00:00')))
        self.assertEqual(intervals[1][:2], (Datetime.from_string('2013-02-19 12:00:00'), Datetime.from_string('2013-02-19 15:45:30')))
        self.assertEqual(intervals[0][2]['attendances'], self.att_1)
        self.assertEqual(intervals[0][2]['leaves'], self.leave1)
        self.assertEqual(intervals[1][2]['attendances'], self.att_1)
        self.assertEqual(intervals[0][2]['leaves'], self.leave1)
Example #22
0
 def test_calendar_working_day_intervals_leaves_resource(self):
     # Test: day1+14 on leave, with resource leave computation
     intervals = self.calendar.get_working_intervals_of_day(
         Datetime.from_string('2013-02-26 07:00:00'),
         compute_leaves=True,
         resource_id=self.resource1_id
     )
     # Result: nothing, because on leave
     self.assertEqual(len(intervals), 0, 'resource_calendar: wrong working interval/day computing')
Example #23
0
    def setUp(self):
        super(TestTimeType, self).setUp()
        Leave = self.env['resource.calendar.leaves']

        self.other1 = Leave.create({
            'name': 'Formation',
            'calendar_id': self.calendar.id,
            'resource_id': self.resource1_id,
            'date_from': Datetime.from_string('2013-02-15 09:00:00'),
            'date_to': Datetime.from_string('2013-02-15 19:00:00'),
            'time_type': 'other',
        })
        self.other2 = Leave.create({
            'name': 'Homeworking',
            'calendar_id': self.calendar.id,
            'resource_id': self.resource1_id,
            'date_from': Datetime.from_string('2013-02-12 09:00:00'),
            'date_to': Datetime.from_string('2013-02-12 15:00:00'),
            'time_type': 'other',
        })
Example #24
0
    def test_calendar_working_day_intervals_no_leaves(self):
        # Test: day0 without leaves: 1 interval
        intervals = self.calendar._get_day_work_intervals(Date.from_string('2013-02-12'), start_time=time(9, 8, 7))
        self.assertEqual(len(intervals), 1)
        self.assertEqual(intervals[0][:2], (Datetime.from_string('2013-02-12 09:08:07'), Datetime.from_string('2013-02-12 16:00:00')))
        self.assertEqual(intervals[0][2]['attendances'], self.att_1)

        # Test: day1, beginning at 10:30 -> work from 10:30 (arrival) until 16:00
        intervals = self.calendar._get_day_work_intervals(Date.from_string('2013-02-19'), start_time=time(10, 30, 0))
        self.assertEqual(len(intervals), 1)
        self.assertEqual(intervals[0][:2], (Datetime.from_string('2013-02-19 10:30:00'), Datetime.from_string('2013-02-19 16:00:00')))
        self.assertEqual(intervals[0][2]['attendances'], self.att_1)

        # Test: day3 without leaves: 2 interval
        intervals = self.calendar._get_day_work_intervals(Date.from_string('2013-02-15'), start_time=time(10, 11, 12))
        self.assertEqual(len(intervals), 2)
        self.assertEqual(intervals[0][:2], (Datetime.from_string('2013-02-15 10:11:12'), Datetime.from_string('2013-02-15 13:00:00')))
        self.assertEqual(intervals[1][:2], (Datetime.from_string('2013-02-15 16:00:00'), Datetime.from_string('2013-02-15 23:00:00')))
        self.assertEqual(intervals[0][2]['attendances'], self.att_2)
        self.assertEqual(intervals[1][2]['attendances'], self.att_3)
Example #25
0
def ctx_tz(record, field):
    res_lang = None
    ctx = record._context
    tz_name = pytz.timezone(ctx.get('tz') or record.env.user.tz)
    timestamp = Datetime.from_string(record[field])
    if ctx.get('lang'):
        res_lang = record.env['res.lang'].search([('code', '=', ctx['lang'])], limit=1)
    if res_lang:
        timestamp = pytz.utc.localize(timestamp, is_dst=False)
        return datetime.strftime(timestamp.astimezone(tz_name), res_lang.date_format + ' ' + res_lang.time_format)
    return Datetime.context_timestamp(record, timestamp)
Example #26
0
    def test_days_count_with_domain(self):
        self.test.resource_id.write({
            'user_id': self.lost_user.id,
        })

        self.env['resource.calendar.leaves'].sudo(self.lost_user).create({
            'name': 'first',
            'calendar_id': self.test.resource_calendar_id.id,
            'resource_id': self.test.resource_id.id,
            'date_from': to_naive_utc(Datetime.from_string('2018-02-05 08:00:00'), self.lost_user),
            'date_to': to_naive_utc(Datetime.from_string('2018-02-09 18:00:00'), self.lost_user)
        })

        self.env['resource.calendar.leaves'].sudo(self.lost_user).create({
            'name': 'second',
            'calendar_id': self.test.resource_calendar_id.id,
            'resource_id': self.test.resource_id.id,
            'date_from': to_naive_utc(Datetime.from_string('2018-01-12 08:00:00'), self.lost_user),
            'date_to': to_naive_utc(Datetime.from_string('2018-01-13 18:00:00'), self.lost_user)
        })

        res = self.test.get_work_days_count(
            to_naive_utc(Datetime.from_string('2018-02-04 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2018-02-14 20:00:00'), self.env.user),
            domain=[('name', '=', '')]
        )
        self.assertEqual(res, 3.0)

        res = self.test.get_work_days_count(
            to_naive_utc(Datetime.from_string('2018-02-04 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2018-02-14 20:00:00'), self.env.user),
            domain=[('name', '=', 'first')]
        )
        self.assertEqual(res, 1.0)

        res = self.test.get_leaves_day_count(
            to_naive_utc(Datetime.from_string('2018-02-04 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2018-02-14 20:00:00'), self.env.user),
            domain=[('name', '=', 'first')]
        )
        self.assertEqual(res, 2.0)
Example #27
0
 def test_calendar_timezone(self):
     # user in timezone UTC-9 asks for work hours
     #  Limits: between 2013-02-19 10:00:00 and 2013-02-26 15:30:00 (User TZ)
     #          between 2013-02-19 19:00:00 and 2013-02-27 00:30:00 (UTC)
     # Leaves:  between 2013-02-21 10:00:00 and 2013-02-26 12:00:00 (User TZ)
     # res: 19/02 (10-16 (beginning)) + 22/02 (0 (leave)) + 26/02 (12-15.30 (leave+ending))
     self.env.user.tz = 'US/Alaska'
     (self.leave1 | self.leave2 | self.leave3).unlink()
     leave = self.env['resource.calendar.leaves'].create({
         'name': 'Timezoned Leaves',
         'calendar_id': self.calendar.id,
         'resource_id': self.resource1_id,
         'date_from': to_naive_utc(Datetime.from_string('2013-02-21 10:00:00'), self.env.user),
         'date_to': to_naive_utc(Datetime.from_string('2013-02-26 12:00:00'), self.env.user)
     })
     res = self.calendar.get_work_hours_count(
         to_naive_utc(Datetime.from_string('2013-02-19 10:00:00'), self.env.user),
         to_naive_utc(Datetime.from_string('2013-02-26 15:30:00'), self.env.user),
         self.resource1_id,
         compute_leaves=True)
     self.assertEqual(res, 9.5)
Example #28
0
 def _check_delay(self, action, record, record_dt):
     """ Override the check of delay to try to use a user-related calendar.
         If no calendar is found, fallback on the default behavior.
     """
     if action.trg_date_calendar_id and action.trg_date_range_type == 'day' and action.trg_date_resource_field_id:
         user = record[action.trg_date_resource_field_id.name]
         if user.employee_ids and user.employee_ids[0].contract_id and user.employee_ids[0].contract_id.working_hours:
             calendar = user.employee_ids[0].contract_id.working_hours
             start_dt = Datetime.from_string(record_dt)
             resource_id = user.employee_ids[0].resource_id.id
             return calendar.schedule_days_get_date(action.trg_date_range, day_date=start_dt, compute_leaves=True, resource_id=resource_id)
     return super(BaseActionRule, self)._check_delay(action, record, record_dt)
Example #29
0
    def test_work_days_count_timezones_ultra(self):
        # user in timezone UTC+4 is attached to the resource and create leaves
        self.test.resource_id.write({
            'user_id': self.lost_user.id,
        })
        reunion_leave = self.env['resource.calendar.leaves'].sudo(self.lost_user).create({
            'name': 'Timezoned Leaves',
            'calendar_id': self.test.resource_calendar_id.id,
            'resource_id': self.test.resource_id.id,
            'date_from': to_naive_utc(Datetime.from_string('2013-02-12 10:00:00'), self.lost_user),
            'date_to': to_naive_utc(Datetime.from_string('2013-02-12 12:00:00'), self.lost_user)
        })
        self.assertEqual(reunion_leave.tz, 'Indian/Reunion')

        # user in timezone UTC-9 read and manipulate leaves
        self.env.user.tz = 'US/Alaska'
        res = self.test.get_work_days_data(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-12 20:00:00'), self.env.user))
        self.assertEqual(res['days'], 0.75)
        self.assertEqual(res['hours'], 6.0)

        # user in timezone UTC+4 read and manipulate leaves
        res = self.test.sudo(self.lost_user).get_work_days_data(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'), self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-12 20:00:00'), self.env.user))
        self.assertEqual(res['days'], 0.75)
        self.assertEqual(res['hours'], 6.0)
Example #30
0
    def setUp(self):
        super(TestGlobalLeaves, self).setUp()

        self.Leave = self.env['resource.calendar.leaves']

        # This leave has a timezone of False : UTC should be used as default
        self.global_no_tz = self.Leave.create({
            'name': 'global no timezone',
            'calendar_id': self.calendar.id,
            'date_from': to_naive_utc(Datetime.from_string('2018-12-25 08:00:00'), self.env.user),
            'date_to': to_naive_utc(Datetime.from_string('2018-12-25 23:00:00'), self.env.user),
            'tz': False,
        })

        # This leave has no timezone defined : should default to user timezone (here UTC)
        self.global_user_tz = self.Leave.create({
            'name': 'global user timezone',
            'calendar_id': self.calendar.id,
            'date_from': to_naive_utc(Datetime.from_string('2018-05-01 08:00:00'), self.env.user),
            'date_to': to_naive_utc(Datetime.from_string('2018-05-01 23:00:00'), self.env.user),
        })

        # This leave has been taken in Japan timezone
        # Leave from 8:00 to 13:00 but we have to adapt cause we define it in UTC
        self.global_spec_tz = self.Leave.create({
            'name': 'global specific timezone',
            'calendar_id': self.calendar.id,
            'date_from': Datetime.from_string('2018-04-05 23:00:00'),
            'date_to': Datetime.from_string('2018-04-06 04:00:00'),
            'tz' : 'Japan', # UTC+9
        })
Example #31
0
    def test_calendar_days_scheduling(self):
        res = self.calendar.plan_days(
            5, Datetime.from_string('2013-02-12 09:08:07'))
        self.assertEqual(res.date(),
                         Datetime.from_string('2013-02-26 00:00:00').date(),
                         'resource_calendar: wrong days scheduling')
        res = self.calendar.plan_days(
            -2, Datetime.from_string('2013-02-12 09:08:07'))
        self.assertEqual(res.date(),
                         Datetime.from_string('2013-02-08 00:00:00').date(),
                         'resource_calendar: wrong days scheduling')

        res = self.calendar.plan_days(
            5,
            Datetime.from_string('2013-02-12 09:08:07'),
            compute_leaves=True,
            resource_id=self.resource1_id)
        self.assertEqual(res.date(),
                         Datetime.from_string('2013-03-01 00:00:00').date(),
                         'resource_calendar: wrong days scheduling')
Example #32
0
    def test_work_days_count_timezones_ultra(self):
        # user in timezone UTC+4 is attached to the resource and create leaves
        self.test.resource_id.write({
            'user_id': self.lost_user.id,
        })
        reunion_leave = self.env['resource.calendar.leaves'].sudo(
            self.lost_user).create({
                'name':
                'Timezoned Leaves',
                'calendar_id':
                self.test.resource_calendar_id.id,
                'resource_id':
                self.test.resource_id.id,
                'date_from':
                to_naive_utc(Datetime.from_string('2013-02-12 10:00:00'),
                             self.lost_user),
                'date_to':
                to_naive_utc(Datetime.from_string('2013-02-12 12:00:00'),
                             self.lost_user)
            })
        self.assertEqual(reunion_leave.tz, 'Indian/Reunion')

        # user in timezone UTC-9 read and manipulate leaves
        self.env.user.tz = 'US/Alaska'
        res = self.test.get_work_days_data(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'),
                         self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-12 20:00:00'),
                         self.env.user))
        self.assertEqual(res['days'], 0.75)
        self.assertEqual(res['hours'], 6.0)

        # user in timezone UTC+4 read and manipulate leaves
        res = self.test.sudo(self.lost_user).get_work_days_data(
            to_naive_utc(Datetime.from_string('2013-02-12 06:00:00'),
                         self.env.user),
            to_naive_utc(Datetime.from_string('2013-02-12 20:00:00'),
                         self.env.user))
        self.assertEqual(res['days'], 0.75)
        self.assertEqual(res['hours'], 6.0)
Example #33
0
    def test_calendar_leave_days_intervals_timezone(self):
        # _get_day_leave_intervals converts from the timezone
        # of the user into UTC
        self.env.user.tz = 'US/Alaska'
        (self.leave1 | self.leave2 | self.leave3).unlink()
        leave = self.env['resource.calendar.leaves'].create({
            'name':
            'Timezoned Leaves',
            'calendar_id':
            self.calendar.id,
            'resource_id':
            self.resource1_id,
            'date_from':
            to_naive_utc(Datetime.from_string('2013-02-21 10:00:00'),
                         self.env.user),
            'date_to':
            to_naive_utc(Datetime.from_string('2013-02-26 12:00:00'),
                         self.env.user)
        })

        def to_tuple(interval):
            return (interval.start_datetime, interval.end_datetime)

        intervals = self.calendar._get_day_leave_intervals(
            Date.from_string('2013-02-26'), time(10), time(18),
            self.resource1_id)
        self.assertEqual(to_tuple(intervals[0]),
                         (Datetime.from_string('2013-02-26 19:00:00'),
                          Datetime.from_string('2013-02-26 21:00:00')))

        self.env.user.tz = 'Japan'

        intervals = self.calendar._get_day_leave_intervals(
            Date.from_string('2013-02-26'), time(10), time(18),
            self.resource1_id)
        self.assertEqual(to_tuple(intervals[0]),
                         (Datetime.from_string('2013-02-26 01:00:00'),
                          Datetime.from_string('2013-02-26 03:00:00')))
Example #34
0
 def test_04(self):
     """After 48 hours"""
     date = Datetime.to_string(Datetime.from_string('2014-01-03 00:00:00'))
     self.mock_datetime.now.return_value = date
     self.assertAlmostEqual(self.line.theoretical_amount, -2)
Example #35
0
 def test_01(self):
     """Start"""
     date = Datetime.to_string(Datetime.from_string('2014-01-01 00:00:00'))
     self.mock_datetime.now.return_value = date
     self.assertAlmostEqual(self.line.theoretical_amount, 0)
Example #36
0
    def test_40_calendar_hours_scheduling(self):
        """ Testing calendar hours scheduling """

        res = self.calendar.schedule_hours(-40,
                                           day_dt=self.date1.replace(minute=0,
                                                                     second=0))
        # current day, limited at 09:00 because of day_dt specified -> 1 hour
        self.assertEqual(res[-1][0],
                         Datetime.from_string('2013-02-12 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-1][1],
                         Datetime.from_string('2013-02-12 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        # previous days: 5+7 hours / 8 hours / 5+7 hours -> 32 hours
        self.assertEqual(res[-2][0],
                         Datetime.from_string('2013-02-08 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-2][1],
                         Datetime.from_string('2013-02-08 23:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-3][0],
                         Datetime.from_string('2013-02-08 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-3][1],
                         Datetime.from_string('2013-02-08 13:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-4][0],
                         Datetime.from_string('2013-02-05 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-4][1],
                         Datetime.from_string('2013-02-05 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-5][0],
                         Datetime.from_string('2013-02-01 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-5][1],
                         Datetime.from_string('2013-02-01 23:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-6][0],
                         Datetime.from_string('2013-02-01 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-6][1],
                         Datetime.from_string('2013-02-01 13:00:00'),
                         'resource_calendar: wrong hours scheduling')
        # 7 hours remaining
        self.assertEqual(res[-7][0],
                         Datetime.from_string('2013-01-29 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[-7][1],
                         Datetime.from_string('2013-01-29 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        # Compute scheduled hours
        td = timedelta()
        for item in res:
            td += item[1] - item[0]
        self.assertEqual(
            seconds(td) / 3600.0, 40.0,
            'resource_calendar: wrong hours scheduling')

        # --------------------------------------------------
        # Test2: schedule hours forward
        # --------------------------------------------------

        res = self.calendar.schedule_hours(40,
                                           day_dt=self.date1.replace(minute=0,
                                                                     second=0))
        self.assertEqual(res[0][0],
                         Datetime.from_string('2013-02-12 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[0][1],
                         Datetime.from_string('2013-02-12 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[1][0],
                         Datetime.from_string('2013-02-15 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[1][1],
                         Datetime.from_string('2013-02-15 13:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[2][0],
                         Datetime.from_string('2013-02-15 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[2][1],
                         Datetime.from_string('2013-02-15 23:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[3][0],
                         Datetime.from_string('2013-02-19 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[3][1],
                         Datetime.from_string('2013-02-19 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[4][0],
                         Datetime.from_string('2013-02-22 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[4][1],
                         Datetime.from_string('2013-02-22 13:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[5][0],
                         Datetime.from_string('2013-02-22 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[5][1],
                         Datetime.from_string('2013-02-22 23:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[6][0],
                         Datetime.from_string('2013-02-26 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[6][1],
                         Datetime.from_string('2013-02-26 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        td = timedelta()
        for item in res:
            td += item[1] - item[0]
        self.assertEqual(
            seconds(td) / 3600.0, 40.0,
            'resource_calendar: wrong hours scheduling')

        res = self.calendar.schedule_hours(40,
                                           day_dt=self.date1.replace(minute=0,
                                                                     second=0),
                                           compute_leaves=True,
                                           resource_id=self.resource1_id)
        self.assertEqual(res[0][0],
                         Datetime.from_string('2013-02-12 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[0][1],
                         Datetime.from_string('2013-02-12 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[1][0],
                         Datetime.from_string('2013-02-15 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[1][1],
                         Datetime.from_string('2013-02-15 13:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[2][0],
                         Datetime.from_string('2013-02-15 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[2][1],
                         Datetime.from_string('2013-02-15 23:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[3][0],
                         Datetime.from_string('2013-02-19 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[3][1],
                         Datetime.from_string('2013-02-19 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[4][0],
                         Datetime.from_string('2013-02-19 12:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[4][1],
                         Datetime.from_string('2013-02-19 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[5][0],
                         Datetime.from_string('2013-02-22 08:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[5][1],
                         Datetime.from_string('2013-02-22 09:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[6][0],
                         Datetime.from_string('2013-02-22 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[6][1],
                         Datetime.from_string('2013-02-22 23:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[7][0],
                         Datetime.from_string('2013-03-01 11:30:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[7][1],
                         Datetime.from_string('2013-03-01 13:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[8][0],
                         Datetime.from_string('2013-03-01 16:00:00'),
                         'resource_calendar: wrong hours scheduling')
        self.assertEqual(res[8][1],
                         Datetime.from_string('2013-03-01 22:30:00'),
                         'resource_calendar: wrong hours scheduling')
        td = timedelta()
        for item in res:
            td += item[1] - item[0]
        self.assertEqual(
            seconds(td) / 3600.0, 40.0,
            'resource_calendar: wrong hours scheduling')

        # --------------------------------------------------
        # Test3: working hours (old _interval_hours_get)
        # --------------------------------------------------

        # old API: resource without leaves
        # res: 2 weeks -> 40 hours
        res = self.calendar._interval_hours_get(
            self.date1.replace(hour=6, minute=0),
            self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
            resource_id=self.resource1_id,
            exclude_leaves=True)
        self.assertEqual(
            res, 40.0,
            'resource_calendar: wrong _interval_hours_get compatibility computation'
        )

        # new API: resource without leaves
        # res: 2 weeks -> 40 hours
        res = self.calendar.get_working_hours(
            self.date1.replace(hour=6, minute=0),
            self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
            compute_leaves=False,
            resource_id=self.resource1_id)
        self.assertEqual(
            res, 40.0,
            'resource_calendar: wrong get_working_hours computation')

        # old API: resource and leaves
        # res: 2 weeks -> 40 hours - (3+4) leave hours
        res = self.calendar._interval_hours_get(
            self.date1.replace(hour=6, minute=0),
            self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
            resource_id=self.resource1_id,
            exclude_leaves=False)
        self.assertEqual(
            res, 33.0,
            'resource_calendar: wrong _interval_hours_get compatibility computation'
        )

        # new API: resource and leaves
        # res: 2 weeks -> 40 hours - (3+4) leave hours
        res = self.calendar.get_working_hours(
            self.date1.replace(hour=6, minute=0),
            self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
            compute_leaves=True,
            resource_id=self.resource1_id)
        self.assertEqual(
            res, 33.0,
            'resource_calendar: wrong get_working_hours computation')

        # --------------------------------------------------
        # Test4: misc
        # --------------------------------------------------

        # Test without calendar and default_interval
        res = self.ResourceCalendar.with_context(
            self.context).get_working_hours(self.date1.replace(hour=6,
                                                               minute=0),
                                            self.date2.replace(hour=23,
                                                               minute=0),
                                            compute_leaves=True,
                                            resource_id=self.resource1_id,
                                            default_interval=(8, 16))
        self.assertEqual(
            res, 32.0,
            'resource_calendar: wrong get_working_hours computation')

        self.att0_0_id = self.ResourceAttendance.with_context(
            self.context).create({
                'name': 'Att0',
                'dayofweek': '0',
                'hour_from': 7.5,
                'hour_to': 12.5,
                'calendar_id': self.calendar.id,
            })
        self.att0_1_id = self.ResourceAttendance.with_context(
            self.context).create({
                'name': 'Att0',
                'dayofweek': '0',
                'hour_from': 13,
                'hour_to': 14,
                'calendar_id': self.calendar.id,
            })
        date1 = Datetime.from_string('2013-02-11 07:30:00')
        date2 = Datetime.from_string('2013-02-11 14:00:00')
        res = self.calendar.get_working_hours(date1,
                                              date2,
                                              compute_leaves=False,
                                              resource_id=self.resource1_id)
        # 7h30 -> 12h30 = 5 / 13h -> 14h = 1 / -> 6h
        self.assertEqual(
            res, 6, 'resource_calendar: wrong get_working_hours computation')
Example #37
0
 def test_06(self):
     """After 50 days"""
     date = Datetime.to_string(Datetime.from_string('2014-02-20 00:00:00'))
     self.mock_datetime.now.return_value = date
     self.assertAlmostEqual(self.line.theoretical_amount, -50)
Example #38
0
 def test_10(self):
     """At last"""
     date = Datetime.to_string(Datetime.from_string('2014-12-31 00:00:00'))
     self.mock_datetime.now.return_value = date
     self.assertAlmostEqual(self.line.theoretical_amount, -364)
    def test_contract_on_another_company(self):
        """ Test that the work entry generation still work if
            the contract is not on the same company than
            the employee (Internal Use Case)
            So when generating the work entries in Belgium,
            there is an issue when accessing to the time off
            in Hong Kong.
        """
        company = self.env['res.company'].create({'name': 'Another Company'})

        employee = self.env['hr.employee'].create({
            'name': 'New Employee',
            'company_id': company.id,
        })

        self.env['hr.contract'].create({
            'name':
            'Employee Contract',
            'employee_id':
            employee.id,
            'date_start':
            Date.from_string('2015-01-01'),
            'state':
            'open',
            'company_id':
            self.env.ref('base.main_company').id,
            'wage':
            4000,
        })

        leave_type = self.env['hr.leave.type'].create({
            'name': 'Sick',
            'request_unit': 'hour',
            'leave_validation_type': 'both',
            'allocation_type': 'no',
            'company_id': company.id,
        })
        leave1 = self.env['hr.leave'].create({
            'name':
            'Sick 1 week during christmas snif',
            'employee_id':
            employee.id,
            'holiday_status_id':
            leave_type.id,
            'date_from':
            Datetime.from_string('2019-12-23 06:00:00'),
            'date_to':
            Datetime.from_string('2019-12-27 20:00:00'),
            'number_of_days':
            5,
        })
        leave1.action_approve()
        leave1.action_validate()

        # The work entries generation shouldn't raise an error

        user = self.env['res.users'].create({
            'name':
            'Classic User',
            'login':
            '******',
            'company_id':
            self.env.ref('base.main_company').id,
            'company_ids':
            self.env.ref('base.main_company').ids,
            'groups_id': [(6, 0, [
                self.env.ref('hr_contract.group_hr_contract_manager').id,
                self.env.ref('base.group_user').id
            ])],
        })
        self.env['hr.employee'].with_user(user).generate_work_entries(
            '2019-12-01', '2019-12-31')
Example #40
0
    def test_calendar_hours_scheduling_forward(self):
        res = self.calendar._schedule_hours(
            40, day_dt=Datetime.from_string('2013-02-12 09:00:00'))
        self.assertEqual(res[0][:2],
                         (Datetime.from_string('2013-02-12 09:00:00'),
                          Datetime.from_string('2013-02-12 16:00:00')))
        self.assertEqual(res[1][:2],
                         (Datetime.from_string('2013-02-15 08:00:00'),
                          Datetime.from_string('2013-02-15 13:00:00')))
        self.assertEqual(res[2][:2],
                         (Datetime.from_string('2013-02-15 16:00:00'),
                          Datetime.from_string('2013-02-15 23:00:00')))
        self.assertEqual(res[3][:2],
                         (Datetime.from_string('2013-02-19 08:00:00'),
                          Datetime.from_string('2013-02-19 16:00:00')))
        self.assertEqual(res[4][:2],
                         (Datetime.from_string('2013-02-22 08:00:00'),
                          Datetime.from_string('2013-02-22 13:00:00')))
        self.assertEqual(res[5][:2],
                         (Datetime.from_string('2013-02-22 16:00:00'),
                          Datetime.from_string('2013-02-22 23:00:00')))
        self.assertEqual(res[6][:2],
                         (Datetime.from_string('2013-02-26 08:00:00'),
                          Datetime.from_string('2013-02-26 09:00:00')))

        td = timedelta()
        for item in res:
            td += item[1] - item[0]
        self.assertEqual(td.total_seconds() / 3600.0, 40.0)

        res = self.calendar.plan_hours(
            40, day_dt=Datetime.from_string('2013-02-12 09:00:00'))
        self.assertEqual(res, Datetime.from_string('2013-02-26 09:00:00'))
Example #41
0
    def setUp(self):
        super(TestResourceCommon, self).setUp()
        self.context = context = dict(tz='UTC')

        self.env['res.users'].browse(self.env.uid).with_context(context).write(
            {'tz': 'UTC'})

        # Usefull models
        self.Resource = self.env['resource.resource']
        self.ResourceCalendar = self.env['resource.calendar']
        self.ResourceAttendance = self.env['resource.calendar.attendance']
        self.ResourceLeaves = self.env['resource.calendar.leaves']

        # Some demo data
        self.date1 = Datetime.from_string(
            '2013-02-12 09:08:07'
        )  # weekday() returns 1, isoweekday() returns 2
        self.date2 = Datetime.from_string(
            '2013-02-15 10:11:12'
        )  # weekday() returns 4, isoweekday() returns 5
        # Leave1: 19/02/2013, from 9 to 12, is a day 1
        self.leave1_start = Datetime.from_string('2013-02-19 09:00:00')
        self.leave1_end = Datetime.from_string('2013-02-19 12:00:00')
        # Leave2: 22/02/2013, from 9 to 15, is a day 4
        self.leave2_start = Datetime.from_string('2013-02-22 09:00:00')
        self.leave2_end = Datetime.from_string('2013-02-22 15:00:00')
        # Leave3: 25/02/2013 (day0) -> 01/03/2013 (day4)
        self.leave3_start = Datetime.from_string('2013-02-25 13:00:00')
        self.leave3_end = Datetime.from_string('2013-03-01 11:30:00')

        # Resource data
        # Calendar working days: 1 (8-16 -> 8hours), 4 (8-13, 16-23 -> 12hours)
        self.calendar = self.ResourceCalendar.with_context(context).create({
            'name':
            'TestCalendar',
        })
        self.att1_id = self.ResourceAttendance.with_context(context).create({
            'name':
            'Att1',
            'dayofweek':
            '1',
            'hour_from':
            8,
            'hour_to':
            16,
            'calendar_id':
            self.calendar.id,
        }).id
        self.att2_id = self.ResourceAttendance.with_context(context).create({
            'name':
            'Att2',
            'dayofweek':
            '4',
            'hour_from':
            8,
            'hour_to':
            13,
            'calendar_id':
            self.calendar.id,
        }).id
        self.att3_id = self.ResourceAttendance.with_context(context).create({
            'name':
            'Att3',
            'dayofweek':
            '4',
            'hour_from':
            16,
            'hour_to':
            23,
            'calendar_id':
            self.calendar.id,
        }).id
        self.resource1_id = self.Resource.with_context(context).create({
            'name':
            'TestResource1',
            'resource_type':
            'user',
            'time_efficiency':
            150.0,
            'calendar_id':
            self.calendar.id,
        }).id
        self.leave1_id = self.ResourceLeaves.with_context(context).create({
            'name':
            'GenericLeave',
            'calendar_id':
            self.calendar.id,
            'date_from':
            self.leave1_start,
            'date_to':
            self.leave1_end,
        }).id
        self.leave2_id = self.ResourceLeaves.with_context(context).create({
            'name':
            'ResourceLeave',
            'calendar_id':
            self.calendar.id,
            'resource_id':
            self.resource1_id,
            'date_from':
            self.leave2_start,
            'date_to':
            self.leave2_end,
        }).id
        self.leave3_id = self.ResourceLeaves.with_context(context).create({
            'name':
            'ResourceLeave2',
            'calendar_id':
            self.calendar.id,
            'resource_id':
            self.resource1_id,
            'date_from':
            self.leave3_start,
            'date_to':
            self.leave3_end,
        }).id
Example #42
0
 def setUp(self):
     super(TestIntervals, self).setUp()
     # Some data intervals
     #  - first one is included in second one
     #  - second one is extended by third one
     #  - sixth one is included in fourth one
     #  - fifth one is prior to other one
     # Once cleaned: 1 interval 03/02 8-10), 2 intervals 04/02 (8-14 + 17-21)
     self.intervals = [
         self.calendar._interval_new(
             Datetime.from_string('2013-02-04 09:00:00'),
             Datetime.from_string('2013-02-04 11:00:00')),
         self.calendar._interval_new(
             Datetime.from_string('2013-02-04 08:00:00'),
             Datetime.from_string('2013-02-04 12:00:00')),
         self.calendar._interval_new(
             Datetime.from_string('2013-02-04 11:00:00'),
             Datetime.from_string('2013-02-04 14:00:00')),
         self.calendar._interval_new(
             Datetime.from_string('2013-02-04 17:00:00'),
             Datetime.from_string('2013-02-04 21:00:00')),
         self.calendar._interval_new(
             Datetime.from_string('2013-02-03 08:00:00'),
             Datetime.from_string('2013-02-03 10:00:00')),
         self.calendar._interval_new(
             Datetime.from_string('2013-02-04 18:00:00'),
             Datetime.from_string('2013-02-04 19:00:00'))
     ]
Example #43
0
    def test_calendar_hours_scheduling_backward(self):
        res = self.calendar._schedule_hours(
            -40, day_dt=Datetime.from_string('2013-02-12 09:00:00'))
        # current day, limited at 09:00 because of day_dt specified -> 1 hour
        self.assertEqual(res[-1][:2],
                         (Datetime.from_string('2013-02-12 08:00:00'),
                          Datetime.from_string('2013-02-12 09:00:00')))
        # previous days: 5+7 hours / 8 hours / 5+7 hours -> 32 hours
        self.assertEqual(res[-2][:2],
                         (Datetime.from_string('2013-02-08 16:00:00'),
                          Datetime.from_string('2013-02-08 23:00:00')))
        self.assertEqual(res[-3][:2],
                         (Datetime.from_string('2013-02-08 08:00:00'),
                          Datetime.from_string('2013-02-08 13:00:00')))
        self.assertEqual(res[-4][:2],
                         (Datetime.from_string('2013-02-05 08:00:00'),
                          Datetime.from_string('2013-02-05 16:00:00')))
        self.assertEqual(res[-5][:2],
                         (Datetime.from_string('2013-02-01 16:00:00'),
                          Datetime.from_string('2013-02-01 23:00:00')))
        self.assertEqual(res[-6][:2],
                         (Datetime.from_string('2013-02-01 08:00:00'),
                          Datetime.from_string('2013-02-01 13:00:00')))
        # 7 hours remaining
        self.assertEqual(res[-7][:2],
                         (Datetime.from_string('2013-01-29 09:00:00'),
                          Datetime.from_string('2013-01-29 16:00:00')))

        # Compute scheduled hours
        td = timedelta()
        for item in res:
            td += item[1] - item[0]
        self.assertEqual(td.total_seconds() / 3600.0, 40.0)

        res = self.calendar.plan_hours(
            -40, day_dt=Datetime.from_string('2013-02-12 09:00:00'))
        self.assertEqual(res, Datetime.from_string('2013-01-29 09:00:00'))
    def recompute_effective_numbers(self):
        for revision in self:
            start_date = revision.week_start_date
            end_date = revision.week_end_date

            # Holds created in the period
            demand_search = [
                ('create_date', '>=', start_date),
                ('create_date', '<=', end_date),
            ]
            resupply_search = [
                ('expiration_date', '>=', start_date),
                ('expiration_date', '<=', end_date),
            ]
            if revision.type == 'web':
                demand_search.append(('channel', '=', 'web'))
                resupply_search.append(('channel', '=', 'web'))
            elif revision.type == 'ambassador':
                demand_search.append(('channel', '=', 'ambassador'))
                resupply_search.append(('channel', '=', 'ambassador'))
            elif revision.type == 'events':
                demand_search.append(('channel', '=', 'event'))
                resupply_search.append(('channel', '=', 'event'))
            elif revision.type == 'sub':
                demand_search.append(('channel', '=', 'sub'))
                resupply_search.append(('channel', '=', 'sub'))
            elif revision.type == 'cancel':
                # This is a special case where we have no holds requested
                # and only resupply by sponsorships cancelled.
                cancellations = self.env['recurring.contract'].search([
                    ('type', 'like', 'S'),
                    ('state', '=', 'terminated'),
                    ('end_date', '>=', start_date),
                    ('end_date', '<=', end_date),
                    ('end_date', '!=', False),
                    ('hold_expiration_date', '!=', False),
                    ('end_reason', '!=', '1'),
                ])
                # Cancellations for which we didn't keep the child on hold
                resupply = len(cancellations.filtered(lambda c: (
                    Datetime.from_string(c.hold_expiration_date) -
                    Datetime.from_string(c.end_date)).total_seconds() < 60
                ))
                # Sponsor Cancel Holds that were released
                resupply_search.extend([
                    ('channel', '=', 'sponsor_cancel'),
                    ('type', '=', HoldType.SPONSOR_CANCEL_HOLD.value),
                ])
                resupply += self.env['compassion.hold'].search_count(
                    resupply_search)
                revision.effective_resupply = resupply
                continue

            hold_obj = self.env['compassion.hold']
            nb_holds = hold_obj.search_count(demand_search)
            resupply = hold_obj.search_count(resupply_search)
            revision.write({
                'holds': nb_holds,
                'effective_resupply': resupply,
            })
        return True
    def recompute_effective_numbers(self):
        depart = self.env.ref("sponsorship_compassion.end_reason_depart")
        for revision in self:
            start_date = revision.week_start_date
            end_date = revision.week_end_date

            # Holds created in the period
            demand_search = [
                ("create_date", ">=", start_date),
                ("create_date", "<=", end_date),
            ]
            resupply_search = [
                ("expiration_date", ">=", start_date),
                ("expiration_date", "<=", end_date),
            ]
            if revision.type == "web":
                demand_search.append(("channel", "=", "web"))
                resupply_search.append(("channel", "=", "web"))
            elif revision.type == "ambassador":
                demand_search.append(("channel", "=", "ambassador"))
                resupply_search.append(("channel", "=", "ambassador"))
            elif revision.type == "events":
                demand_search.append(("channel", "=", "event"))
                resupply_search.append(("channel", "=", "event"))
            elif revision.type == "sub":
                demand_search.append(("channel", "=", "sub"))
                resupply_search.append(("channel", "=", "sub"))
            elif revision.type == "cancel":
                # This is a special case where we have no holds requested
                # and only resupply by sponsorships cancelled.
                cancellations = self.env["recurring.contract"].search([
                    ("type", "like", "S"),
                    ("state", "=", "terminated"),
                    ("end_date", ">=", start_date),
                    ("end_date", "<=", end_date),
                    ("end_date", "!=", False),
                    ("hold_expiration_date", "!=", False),
                    ("end_reason_id", "!=", depart.id),
                ])
                # Cancellations for which we didn't keep the child on hold
                resupply = len(
                    cancellations.filtered(lambda c: (Datetime.from_string(
                        c.hold_expiration_date) - Datetime.from_string(
                            c.end_date)).total_seconds() < 60))
                # Sponsor Cancel Holds that were released
                resupply_search.extend([
                    ("channel", "=", "sponsor_cancel"),
                    ("type", "=", HoldType.SPONSOR_CANCEL_HOLD.value),
                ])
                resupply += self.env["compassion.hold"].search_count(
                    resupply_search)
                revision.effective_resupply = resupply
                continue

            hold_obj = self.env["compassion.hold"]
            nb_holds = hold_obj.search_count(demand_search)
            resupply = hold_obj.search_count(resupply_search)
            revision.write({
                "holds": nb_holds,
                "effective_resupply": resupply,
            })
        return True
Example #46
0
    def generate_xlsx_report(self, workbook, data, attendances):

        # Setup sheet and data
        report_name = "ATTENDANCE FROM " + str(
            data['form']['date_from']) + " TO " + data['form']['date_to']
        all_employees = self.env['hr.employee'].search([])
        # Parse date from and date to type date
        date_from = datetime.strptime(data['form']['date_from'], "%Y-%m-%d")
        date_to = datetime.strptime(data['form']['date_to'], "%Y-%m-%d")

        # Get all dates between the date from and date to dates
        dates = []
        delta = date_to - date_from  # as timedelta

        for i in range(delta.days + 1):
            day = date_from + timedelta(days=i)
            dates.append(day)

        employees = all_employees[:]
        employees = employees.sorted(lambda e: e.department_id.sequence
                                     if e.department_id else 1000)

        # Setup columns
        sheet = workbook.add_worksheet(report_name[:31])
        titles = workbook.add_format({'align': 'center', 'bold': True})
        center = workbook.add_format({'align': 'center'})
        t_heading = workbook.add_format({
            'align': 'center',
            'bold': True,
            'bg_color': '#BD5B5B',
            'border': 1,
            'valign': 'vcenter'
        })
        sheet.set_column('B:B', 10)
        sheet.set_column('C:C', 35)
        sheet.set_column('D:D', 30)
        sheet.set_column('E:E', 35)

        # Add company logo
        # logo = self.env.user.sudo().company_id.logo
        # imgdata = base64.b64decode(logo)
        # image = io.BytesIO(imgdata)
        # sheet.insert_image(0, 1, 'python.png', {'x_scale': 0.5, 'y_scale': 0.5, 'image_data': image})

        # Print dates between date from and date to
        dates_column = 5
        dates_format = workbook.add_format({'align': 'center'})
        for a_date in dates:
            sheet.merge_range(6, dates_column, 6, dates_column + 1,
                              a_date.strftime("%d-%b"), dates_format)
            sheet.set_column(dates_column + 2, dates_column + 2, 15)
            sheet.write_row(7, dates_column,
                            ['Enter', 'Exit', 'Working Hours'], t_heading)
            dates_column += 3

        # Headings and titles
        sheet.merge_range(0, 2, 0, dates_column, 'HR DEPARTMENT', titles)
        sheet.merge_range(1, 2, 1, dates_column, 'ATTENDANCE REPORT', titles)
        sheet.merge_range(3, 2, 3, dates_column, "AVERAGE WORKING HOURS",
                          titles)
        sheet.merge_range(
            5, 2, 5, dates_column, 'FROM : ' + date_from.strftime("%d-%b") +
            ' TO : ' + date_to.strftime("%d-%b"), center)
        sheet.write_row('B8',
                        ['Employee \nID', 'Name', 'Job Title', 'Department'],
                        t_heading)

        # Continue titles and company logo after days printed
        # sheet.insert_image(0, dates_column, 'python.png', {'x_scale': 0.5, 'y_scale': 0.5, 'image_data': image})
        sheet.set_column(dates_column, dates_column, 11)
        sheet.write(7, dates_column, 'Average \nWorking \nHours', t_heading)
        sheet.set_row(7, 60)
        row = 1
        for obj in employees:
            num_days = 0
            total_hours = 0
            if len(obj.machine_attendance_ids) > 0:
                rgb_color = obj.department_id.color
                if not rgb_color:
                    rgb_color = "rgba(255,0,0,1)"
                color = '#FFFFFF'
                if len(rgb_color) > 1:
                    color = rgb_to_hex(
                        eval(rgb_color[rgb_color.index('('):rgb_color.
                                       rindex(',')] + ")"))
                color = color.upper()
                emp_id = workbook.add_format({
                    'bg_color': '#F09481',
                    'align': 'center',
                    'border': 1
                })
                attendance = workbook.add_format({
                    'bg_color': color,
                    'align': 'center',
                    'border': 1
                })
                time = workbook.add_format({
                    'bg_color': 'silver',
                    'align': 'center',
                    'border': 1
                })
                sheet.write_row('B' + str(row + 8), [row], emp_id)
                sheet.write_row('C' + str(row + 8), [
                    obj.name, obj.job_id.name or '-', obj.department_id.name
                    or '-'
                ], attendance)
                employee_attendance_ids = \
                    obj.machine_attendance_ids.filtered(lambda a:
                                                        date_to >=
                                                        ODT.from_string(ODT.context_timestamp(a,
                                                                                              ODT.from_string(
                                                                                                  a.punching_time)).
                                                                        strftime("%Y-%m-%d")) >= date_from)
                day_column = 5
                for a_date in dates:
                    a_date_attendances = employee_attendance_ids.filtered(
                        lambda attend: ODT.context_timestamp(
                            attend, ODT.from_string(attend.punching_time)
                        ).strftime('%Y-%m-%d') == a_date.strftime("%Y-%m-%d"))
                    if a_date_attendances:
                        first_check_in_rec = a_date_attendances.sorted(
                            lambda a: a.punching_time)[0]
                        last_check_out_rec = a_date_attendances.sorted(
                            lambda a: a.punching_time)[-1]
                        first_check_in = first_check_in_rec.punching_time
                        last_check_out = last_check_out_rec.punching_time
                        worked_hours = 0
                        if first_check_in == last_check_out:
                            last_check_out = '-'
                        else:
                            delta = datetime.strptime(last_check_out, DEFAULT_SERVER_DATETIME_FORMAT) - \
                                    datetime.strptime(first_check_in, DEFAULT_SERVER_DATETIME_FORMAT)
                            worked_hours = delta.total_seconds() / 3600.0
                            last_check_out = ODT.context_timestamp(
                                obj, ODT.from_string(last_check_out)).strftime(
                                    '%H:%M')
                        num_days += 1
                        total_hours += worked_hours
                        first_check_in = ODT.context_timestamp(
                            obj,
                            ODT.from_string(first_check_in)).strftime('%H:%M')
                        sheet.write_row(row + 7, day_column, [
                            first_check_in, last_check_out,
                            round(worked_hours, 2)
                        ], time)
                    else:
                        sheet.write_row(row + 7, day_column, ['-', '-', '-'],
                                        time)
                    day_column += 3
                employee_avg = 0 if num_days == 0 or total_hours == 0 else total_hours / num_days
                employee_avg = round(employee_avg, 2)
                sheet.write(
                    row + 7, dates_column, employee_avg,
                    workbook.add_format({
                        'align': 'center',
                        'border': 1
                    }))
                row += 1
Example #47
0
    def test_simple_flow(self):
        date = Datetime.from_string(
            '2014-08-01 15:02:32')  # so long, little task
        self.mock_datetime.now.return_value = date
        self.mock_datetime2.now.return_value = date

        Campaign = self.env['marketing.campaign'].with_user(self.user_market)
        Activity = self.env['marketing.activity'].with_user(self.user_market)
        MassMail = self.env['mailing.mailing'].with_user(self.user_market)
        ServerAction = self.env['ir.actions.server'].with_user(
            self.user_market)

        # Create campaign
        campaign = Campaign.create({
            'name':
            'My First Campaign',
            'model_id':
            self.test_model.id,
            'domain':
            '%s' % ([('name', '!=', 'Invalid')]),
        })

        # Create first activity flow
        mass_mailing = MassMail.create({
            'name': 'Hello',
            'subject': 'Hello',
            'body_html': '<div>My Email Body</div>',
            'mailing_model_id': self.test_model.id,
            'use_in_marketing_automation': True,
        })
        act_0 = Activity.create({
            'name': 'Enter the campaign',
            'campaign_id': campaign.id,
            'activity_type': 'email',
            'mass_mailing_id': mass_mailing.id,
            'trigger_type': 'begin',
            'interval_number': '0',
        })

        # NOTSURE: let us consider currently that a smart admin created the server action for the marketing user, is probably the case actually
        server_action = ServerAction.sudo().create({
            'name':
            'Update name',
            'state':
            'code',
            'model_id':
            self.test_model.id,
            'code':
            '''
for record in records:
    record.write({'name': record.name + 'SA'})'''
        })
        act_1 = Activity.create({
            'name':
            'Update name',
            'activity_domain':
            '%s' % ([('name', 'ilike', 'Test')]),
            'campaign_id':
            campaign.id,
            'parent_id':
            act_0.id,
            'activity_type':
            'action',
            'server_action_id':
            server_action.id,
            'trigger_type':
            'act',
            'interval_number':
            '1',
            'interval_type':
            'hours',
        })

        # User starts and syncs its campaign
        campaign.action_start_campaign()
        self.assertEqual(campaign.state, 'running')
        campaign.sync_participants()

        # All records not containing Invalid should be added as participants
        self.assertEqual(campaign.running_participant_count, 4)
        self.assertEqual(
            set(campaign.participant_ids.mapped('res_id')),
            set((self.test_rec1 | self.test_rec2 | self.test_rec3
                 | self.test_rec4).ids))
        self.assertEqual(set(campaign.participant_ids.mapped('state')),
                         set(['running']))

        # Begin activity should contain a trace for each participant
        self.assertEqual(
            act_0.trace_ids.mapped('participant_id'),
            campaign.participant_ids,
        )
        self.assertEqual(set(act_0.trace_ids.mapped('state')),
                         set(['scheduled']))
        self.assertEqual(set(act_0.trace_ids.mapped('schedule_date')),
                         set([date]))

        # No other trace should have been created as the first one are waiting to be processed
        self.assertEqual(act_1.trace_ids, self.env['marketing.trace'])

        # First traces are processed, emails are sent
        with patch.object(IrMailServer, 'connect'):
            campaign.execute_activities()
        self.assertEqual(set(act_0.trace_ids.mapped('state')),
                         set(['processed']))

        # Child traces should have been generated for all traces of parent activity as filter is taken into account at processing, not generation
        self.assertEqual(
            set(act_1.trace_ids.mapped('participant_id.res_id')),
            set((self.test_rec1 | self.test_rec2 | self.test_rec3
                 | self.test_rec4).ids))
        self.assertEqual(set(act_1.trace_ids.mapped('state')),
                         set(['scheduled']))
        self.assertEqual(set(act_1.trace_ids.mapped('schedule_date')),
                         set([date + relativedelta(hours=1)]))

        # Traces are processed, but this is not the time to execute child traces
        campaign.execute_activities()
        self.assertEqual(set(act_1.trace_ids.mapped('state')),
                         set(['scheduled']))

        # Time is coming, a bit like the winter
        date = Datetime.from_string(
            '2014-08-01 17:02:32'
        )  # wow, a two hour span ! so much incredible !
        self.mock_datetime.now.return_value = date
        self.mock_datetime2.now.return_value = date

        campaign.execute_activities()
        # There should be one rejected activity not matching the filter
        self.assertEqual(
            set(
                act_1.trace_ids.filtered(lambda tr: tr.participant_id.res_id !=
                                         self.test_rec4.id).mapped('state')),
            set(['processed']))
        self.assertEqual(
            set(
                act_1.trace_ids.filtered(lambda tr: tr.participant_id.res_id ==
                                         self.test_rec4.id).mapped('state')),
            set(['rejected']))
        # Check server action was actually processed
        self.assertTrue([
            'SA' in record.name
            for record in self.test_rec1 | self.test_rec2 | self.test_rec3
        ])
        self.assertTrue(['SA' not in record.name for record in self.test_rec4])
Example #48
0
    def test_calendar_hours_scheduling_forward_leaves_resource(self):
        res = self.calendar._schedule_hours(
            40,
            day_dt=Datetime.from_string('2013-02-12 09:00:00'),
            compute_leaves=True,
            resource_id=self.resource1_id)
        self.assertEqual(res[0][:2],
                         (Datetime.from_string('2013-02-12 09:00:00'),
                          Datetime.from_string('2013-02-12 16:00:00')))
        self.assertEqual(res[1][:2],
                         (Datetime.from_string('2013-02-15 08:00:00'),
                          Datetime.from_string('2013-02-15 13:00:00')))
        self.assertEqual(res[2][:2],
                         (Datetime.from_string('2013-02-15 16:00:00'),
                          Datetime.from_string('2013-02-15 23:00:00')))
        self.assertEqual(res[3][:2],
                         (Datetime.from_string('2013-02-19 08:00:00'),
                          Datetime.from_string('2013-02-19 09:00:00')))
        self.assertEqual(res[4][:2],
                         (Datetime.from_string('2013-02-19 12:00:00'),
                          Datetime.from_string('2013-02-19 16:00:00')))
        self.assertEqual(res[5][:2],
                         (Datetime.from_string('2013-02-22 08:00:00'),
                          Datetime.from_string('2013-02-22 09:00:00')))
        self.assertEqual(res[6][:2],
                         (Datetime.from_string('2013-02-22 16:00:00'),
                          Datetime.from_string('2013-02-22 23:00:00')))
        self.assertEqual(res[7][:2],
                         (Datetime.from_string('2013-03-01 11:30:00'),
                          Datetime.from_string('2013-03-01 13:00:00')))
        self.assertEqual(res[8][:2],
                         (Datetime.from_string('2013-03-01 16:00:00'),
                          Datetime.from_string('2013-03-01 22:30:00')))

        td = timedelta()
        for item in res:
            td += item[1] - item[0]
        self.assertEqual(td.total_seconds() / 3600.0, 40.0)
Example #49
0
    def action_update_participants(self):
        """ Synchronizes all participants based campaign activities demanding synchronization
        It is done in 2 part:

         * update traces related to updated activities. This means basically recomputing the
           schedule date
         * creating new traces for activities recently added in the workflow :

          * 'begin' activities simple create new traces for all running participants;
          * other activities: create child for traces linked to the parent of the newly created activity
          * we consider scheduling to be done after parent processing, independently of other time considerations
          * for 'not' triggers take into account brother traces that could be already processed
        """
        for campaign in self:
            # Action 1: On activity modification
            modified_activities = campaign.marketing_activity_ids.filtered(
                lambda activity: activity.require_sync)
            traces_to_reschedule = self.env['marketing.trace'].search([
                ('state', '=', 'scheduled'),
                ('activity_id', 'in', modified_activities.ids)
            ])
            for trace in traces_to_reschedule:
                trace_offset = relativedelta(
                    **{
                        trace.activity_id.interval_type:
                        trace.activity_id.interval_number
                    })
                trigger_type = trace.activity_id.trigger_type
                if trigger_type == 'begin':
                    trace.schedule_date = Datetime.from_string(
                        trace.participant_id.create_date) + trace_offset
                elif trigger_type in [
                        'act', 'mail_not_open', 'mail_not_click',
                        'mail_not_reply'
                ] and trace.parent_id:
                    trace.schedule_date = Datetime.from_string(
                        trace.parent_id.schedule_date) + trace_offset
                elif trace.parent_id:
                    process_dt = trace.parent_id.mailing_trace_ids.state_update
                    trace.schedule_date = Datetime.from_string(
                        process_dt) + trace_offset

            # Action 2: On activity creation
            created_activities = campaign.marketing_activity_ids.filtered(
                lambda a: a.create_date >= campaign.last_sync_date)
            for activity in created_activities:
                activity_offset = relativedelta(
                    **{activity.interval_type: activity.interval_number})
                # Case 1: Trigger = begin
                # Create new root traces for all running participants -> consider campaign begin date is now to avoid spamming participants
                if activity.trigger_type == 'begin':
                    participants = self.env['marketing.participant'].search([
                        ('state', '=', 'running'),
                        ('campaign_id', '=', campaign.id)
                    ])
                    for participant in participants:
                        schedule_date = Datetime.from_string(
                            Datetime.now()) + activity_offset
                        self.env['marketing.trace'].create({
                            'activity_id':
                            activity.id,
                            'participant_id':
                            participant.id,
                            'schedule_date':
                            schedule_date,
                        })
                else:
                    valid_parent_traces = self.env['marketing.trace'].search([
                        ('state', '=', 'processed'),
                        ('activity_id', '=', activity.parent_id.id)
                    ])

                    # avoid creating new traces that would have processed brother traces already processed
                    # example: do not create a mail_not_click trace if mail_click is already processed
                    if activity.trigger_type in [
                            'mail_not_open', 'mail_not_click', 'mail_not_reply'
                    ]:
                        opposite_trigger = activity.trigger_type.replace(
                            '_not_', '_')
                        brother_traces = self.env['marketing.trace'].search([
                            ('parent_id', 'in', valid_parent_traces.ids),
                            ('trigger_type', '=', opposite_trigger),
                            ('state', '=', 'processed'),
                        ])
                        valid_parent_traces = valid_parent_traces - brother_traces.mapped(
                            'parent_id')

                    valid_parent_traces.mapped('participant_id').filtered(
                        lambda participant: participant.state == 'completed'
                    ).action_set_running()

                    for parent_trace in valid_parent_traces:
                        self.env['marketing.trace'].create({
                            'activity_id':
                            activity.id,
                            'participant_id':
                            parent_trace.participant_id.id,
                            'parent_id':
                            parent_trace.id,
                            'schedule_date':
                            Datetime.from_string(parent_trace.schedule_date) +
                            activity_offset,
                        })

        self.action_set_synchronized()
Example #50
0
    def setUpClass(cls):
        super(TestLeadConvertCommon, cls).setUpClass()
        # Sales Team organization
        # Role: M (team member) R (team manager)
        # SALESMAN---------------sales_team_1-----sales_team_convert
        # admin------------------M----------------/  (sales_team_1_m2)
        # user_sales_manager-----R----------------R
        # user_sales_leads-------M----------------/  (sales_team_1_m1)
        # user_sales_salesman----/----------------M  (sales_team_convert_m1)

        # Stages Team organization
        # Name-------------------ST-------------------Sequ
        # stage_team1_1----------sales_team_1---------1
        # stage_team1_2----------sales_team_1---------5
        # stage_team1_won--------sales_team_1---------70
        # stage_gen_1------------/--------------------3
        # stage_gen_won----------/--------------------30
        # stage_team_convert_1---sales_team_convert---1

        cls.sales_team_convert = cls.env['crm.team'].create({
            'name':
            'Convert Sales Team',
            'sequence':
            10,
            'alias_name':
            False,
            'use_leads':
            True,
            'use_opportunities':
            True,
            'company_id':
            False,
            'user_id':
            cls.user_sales_manager.id,
            'assignment_domain': [('priority', 'in', ['1', '2', '3'])],
        })
        cls.sales_team_convert_m1 = cls.env['crm.team.member'].create({
            'user_id':
            cls.user_sales_salesman.id,
            'crm_team_id':
            cls.sales_team_convert.id,
            'assignment_max':
            30,
            'assignment_domain':
            False,
        })
        cls.stage_team_convert_1 = cls.env['crm.stage'].create({
            'name':
            'New',
            'sequence':
            1,
            'team_id':
            cls.sales_team_convert.id,
        })

        cls.lead_1.write(
            {'date_open': Datetime.from_string('2020-01-15 11:30:00')})

        cls.crm_lead_dt_patcher = patch(
            'odoo.addons.crm.models.crm_lead.fields.Datetime', wraps=Datetime)
        cls.crm_lead_dt_mock = cls.crm_lead_dt_patcher.start()
Example #51
0
 def test_45_calendar_hours_scheduling_minutes(self):
     """ Testing minutes computation in calendar hours scheduling """
     res = self.calendar.schedule_hours_get_date(-39,
                                                 day_dt=self.date1.replace(
                                                     minute=25, second=20))
     self.assertEqual(res, Datetime.from_string('2013-01-29 10:25:20'))
Example #52
0
    def test_20_calendar_working_intervals(self):
        """ Testing working intervals computing method of resource.calendar """

        # Test: day0 without leaves: 1 interval
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1)
        self.assertEqual(len(intervals), 1,
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][0],
                         Datetime.from_string('2013-02-12 09:08:07'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][1],
                         Datetime.from_string('2013-02-12 16:00:00'),
                         'resource_calendar: wrong working intervals')

        # Test: day3 without leaves: 2 interval
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date2)
        self.assertEqual(len(intervals), 2,
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][0],
                         Datetime.from_string('2013-02-15 10:11:12'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][1],
                         Datetime.from_string('2013-02-15 13:00:00'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[1][0],
                         Datetime.from_string('2013-02-15 16:00:00'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[1][1],
                         Datetime.from_string('2013-02-15 23:00:00'),
                         'resource_calendar: wrong working intervals')

        # Test: day0 with leaves outside range: 1 interval
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=0), compute_leaves=True)
        self.assertEqual(len(intervals), 1,
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][0],
                         Datetime.from_string('2013-02-12 08:00:00'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][1],
                         Datetime.from_string('2013-02-12 16:00:00'),
                         'resource_calendar: wrong working intervals')

        # Test: day0 with leaves: 2 intervals because of leave between 9 ans 12, ending at 15:45:30
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=8) + relativedelta(days=7),
            end_dt=self.date1.replace(hour=15, minute=45, second=30) +
            relativedelta(days=7),
            compute_leaves=True)
        self.assertEqual(len(intervals), 2,
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][0],
                         Datetime.from_string('2013-02-19 08:08:07'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[0][1],
                         Datetime.from_string('2013-02-19 09:00:00'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[1][0],
                         Datetime.from_string('2013-02-19 12:00:00'),
                         'resource_calendar: wrong working intervals')
        self.assertEqual(intervals[1][1],
                         Datetime.from_string('2013-02-19 15:45:30'),
                         'resource_calendar: wrong working intervals')
 def action_delayed_line(self):
     raise UserError(
         _('This line is scheduled for: %s. \n However it is now planned to '
           'arrive late.') %
         Dt.to_string(
             Dt.context_timestamp(self, Dt.from_string(self.date_planned))))
Example #54
0
    def test_lead_convert_batch_internals(self):
        """ Test internals of convert wizard, working in batch mode """
        date = Datetime.from_string('2020-01-20 16:00:00')
        self.crm_lead_dt_mock.now.return_value = date

        lead_w_partner = self.lead_w_partner
        self.assertEqual(lead_w_partner.user_id, self.user_sales_manager)
        self.assertEqual(lead_w_partner.team_id, self.sales_team_1)
        self.assertEqual(lead_w_partner.stage_id, self.env['crm.stage'])
        lead_w_contact = self.lead_w_contact
        self.assertEqual(lead_w_contact.user_id, self.user_sales_salesman)
        self.assertEqual(lead_w_contact.team_id, self.sales_team_convert)
        self.assertEqual(lead_w_contact.stage_id, self.stage_gen_1)
        lead_w_email_lost = self.lead_w_email_lost
        self.assertEqual(lead_w_email_lost.user_id, self.user_sales_leads)
        self.assertEqual(lead_w_email_lost.team_id, self.sales_team_1)
        self.assertEqual(lead_w_email_lost.stage_id, self.stage_team1_2)
        lead_w_email_lost.action_set_lost()
        self.assertEqual(lead_w_email_lost.active, False)

        convert = self.env['crm.lead2opportunity.partner'].with_context({
            'active_model':
            'crm.lead',
            'active_id':
            self.lead_1.id,
            'active_ids': (self.lead_1 | lead_w_partner | lead_w_contact
                           | lead_w_email_lost).ids,
        }).create({})

        # test internals of convert wizard
        # self.assertEqual(convert.lead_id, self.lead_1)
        self.assertEqual(convert.user_id, self.lead_1.user_id)
        self.assertEqual(convert.team_id, self.lead_1.team_id)
        self.assertFalse(convert.partner_id)
        self.assertEqual(convert.name, 'convert')
        self.assertEqual(convert.action, 'create')

        convert.action_apply()
        self.assertEqual(convert.user_id, self.user_sales_leads)
        self.assertEqual(convert.team_id, self.sales_team_1)
        # lost leads are not converted (see crm_lead.convert_opportunity())
        self.assertFalse(lead_w_email_lost.active)
        self.assertFalse(lead_w_email_lost.date_conversion)
        self.assertEqual(lead_w_email_lost.partner_id, self.env['res.partner'])
        self.assertEqual(lead_w_email_lost.stage_id,
                         self.stage_team1_2)  # did not change
        # other leads are converted into opportunities
        for opp in (self.lead_1 | lead_w_partner | lead_w_contact):
            # team management update: opportunity linked to chosen wizard values
            self.assertEqual(opp.type, 'opportunity')
            self.assertTrue(opp.active)
            self.assertEqual(opp.user_id, convert.user_id)
            self.assertEqual(opp.team_id, convert.team_id)
            # dates update: convert set them to now
            self.assertEqual(opp.date_open, date)
            self.assertEqual(opp.date_conversion, date)
            # stage update (depends on previous value)
            if opp == self.lead_1:
                self.assertEqual(opp.stage_id,
                                 self.stage_team1_1)  # did not change
            elif opp == lead_w_partner:
                self.assertEqual(opp.stage_id, self.stage_team1_1
                                 )  # is set to default stage of sales_team_1
            elif opp == lead_w_contact:
                self.assertEqual(opp.stage_id,
                                 self.stage_gen_1)  # did not change
            else:
                self.assertFalse(True)
Example #55
0
    def test_00_intervals(self):
        intervals = [(Datetime.from_string('2013-02-04 09:00:00'),
                      Datetime.from_string('2013-02-04 11:00:00')),
                     (Datetime.from_string('2013-02-04 08:00:00'),
                      Datetime.from_string('2013-02-04 12:00:00')),
                     (Datetime.from_string('2013-02-04 11:00:00'),
                      Datetime.from_string('2013-02-04 14:00:00')),
                     (Datetime.from_string('2013-02-04 17:00:00'),
                      Datetime.from_string('2013-02-04 21:00:00')),
                     (Datetime.from_string('2013-02-03 08:00:00'),
                      Datetime.from_string('2013-02-03 10:00:00')),
                     (Datetime.from_string('2013-02-04 18:00:00'),
                      Datetime.from_string('2013-02-04 19:00:00'))]

        # Test: interval cleaning
        cleaned_intervals = self.ResourceCalendar.interval_clean(intervals)
        self.assertEqual(len(cleaned_intervals), 3,
                         'resource_calendar: wrong interval cleaning')
        # First interval: 03, unchanged
        self.assertEqual(cleaned_intervals[0][0],
                         Datetime.from_string('2013-02-03 08:00:00'),
                         'resource_calendar: wrong interval cleaning')
        self.assertEqual(cleaned_intervals[0][1],
                         Datetime.from_string('2013-02-03 10:00:00'),
                         'resource_calendar: wrong interval cleaning')
        # Second intreval: 04, 08-14, combining 08-12 and 11-14, 09-11 being inside 08-12
        self.assertEqual(cleaned_intervals[1][0],
                         Datetime.from_string('2013-02-04 08:00:00'),
                         'resource_calendar: wrong interval cleaning')
        self.assertEqual(cleaned_intervals[1][1],
                         Datetime.from_string('2013-02-04 14:00:00'),
                         'resource_calendar: wrong interval cleaning')
        # Third interval: 04, 17-21, 18-19 being inside 17-21
        self.assertEqual(cleaned_intervals[2][0],
                         Datetime.from_string('2013-02-04 17:00:00'),
                         'resource_calendar: wrong interval cleaning')
        self.assertEqual(cleaned_intervals[2][1],
                         Datetime.from_string('2013-02-04 21:00:00'),
                         'resource_calendar: wrong interval cleaning')

        # Test: disjoint removal
        working_interval = (Datetime.from_string('2013-02-04 08:00:00'),
                            Datetime.from_string('2013-02-04 18:00:00'))
        result = self.ResourceCalendar.interval_remove_leaves(
            working_interval, intervals)
        self.assertEqual(
            len(result), 1,
            'resource_calendar: wrong leave removal from interval')
        # First interval: 04, 14-17
        self.assertEqual(
            result[0][0], Datetime.from_string('2013-02-04 14:00:00'),
            'resource_calendar: wrong leave removal from interval')
        self.assertEqual(
            result[0][1], Datetime.from_string('2013-02-04 17:00:00'),
            'resource_calendar: wrong leave removal from interval')

        # Test: schedule hours on intervals
        result = self.ResourceCalendar.interval_schedule_hours(
            cleaned_intervals, 5.5)
        self.assertEqual(
            len(result), 2,
            'resource_calendar: wrong hours scheduling in interval')
        # First interval: 03, 8-10 untouches
        self.assertEqual(
            result[0][0], Datetime.from_string('2013-02-03 08:00:00'),
            'resource_calendar: wrong leave removal from interval')
        self.assertEqual(
            result[0][1], Datetime.from_string('2013-02-03 10:00:00'),
            'resource_calendar: wrong leave removal from interval')
        # First interval: 04, 08-11:30
        self.assertEqual(
            result[1][0], Datetime.from_string('2013-02-04 08:00:00'),
            'resource_calendar: wrong leave removal from interval')
        self.assertEqual(
            result[1][1], Datetime.from_string('2013-02-04 11:30:00'),
            'resource_calendar: wrong leave removal from interval')

        # Test: schedule hours on intervals, backwards
        cleaned_intervals.reverse()
        result = self.ResourceCalendar.interval_schedule_hours(
            cleaned_intervals, 5.5, remove_at_end=False)
        self.assertEqual(
            len(result), 2,
            'resource_calendar: wrong hours scheduling in interval')
        # First interval: 03, 8-10 untouches
        self.assertEqual(
            result[0][0], Datetime.from_string('2013-02-04 17:00:00'),
            'resource_calendar: wrong leave removal from interval')
        self.assertEqual(
            result[0][1], Datetime.from_string('2013-02-04 21:00:00'),
            'resource_calendar: wrong leave removal from interval')
        # First interval: 04, 08-11:30
        self.assertEqual(
            result[1][0], Datetime.from_string('2013-02-04 12:30:00'),
            'resource_calendar: wrong leave removal from interval')
        self.assertEqual(
            result[1][1], Datetime.from_string('2013-02-04 14:00:00'),
            'resource_calendar: wrong leave removal from interval')
Example #56
0
    def setUp(self):
        super(TestResourceCommon, self).setUp()
        self.env.user.tz = 'UTC'

        # Some demo data
        self.date1 = Datetime.from_string('2013-02-12 09:08:07')  # weekday() returns 1, isoweekday() returns 2
        self.date2 = Datetime.from_string('2013-02-15 10:11:12')  # weekday() returns 4, isoweekday() returns 5

        # Resource data
        # Calendar working days: 1 (8-16 -> 8hours), 4 (8-13, 16-23 -> 12hours)
        self.calendar = self.env['resource.calendar'].create({
            'name': 'TestCalendar',
            'attendance_ids': [(5, 0, 0)]
        })
        self.att_1 = self.env['resource.calendar.attendance'].create({
            'name': 'Att1',
            'calendar_id': self.calendar.id,
            'dayofweek': '1',
            'hour_from': 8,
            'hour_to': 16
        })
        self.att_2 = self.env['resource.calendar.attendance'].create({
            'name': 'Att2',
            'calendar_id': self.calendar.id,
            'dayofweek': '4',
            'hour_from': 8,
            'hour_to': 13
        })
        self.att_3 = self.env['resource.calendar.attendance'].create({
            'name': 'Att3',
            'calendar_id': self.calendar.id,
            'dayofweek': '4',
            'hour_from': 16,
            'hour_to': 23
        })

        self.resource1_id = self.env['resource.resource'].create(
            {
                'name': 'TestResource1',
                'resource_type': 'user',
                'time_efficiency': 150.0,
                'calendar_id': self.calendar.id,
            }
        ).id

        # Leave1: 19/02/2013, from 9 to 12, is a day 1
        self.leave1 = self.env['resource.calendar.leaves'].create({
            'name': 'GenericLeave',
            'calendar_id': self.calendar.id,
            'date_from': Datetime.from_string('2013-02-19 09:00:00'),
            'date_to': Datetime.from_string('2013-02-19 12:00:00')})
        # Leave2: 22/02/2013, from 9 to 15, is a day 4
        self.leave2 = self.env['resource.calendar.leaves'].create({
            'name': 'ResourceLeave',
            'calendar_id': self.calendar.id,
            'resource_id': self.resource1_id,
            'date_from': Datetime.from_string('2013-02-22 09:00:00'),
            'date_to': Datetime.from_string('2013-02-22 15:00:00')})
        # Leave3: 25/02/2013 (day0) -> 01/03/2013 (day4)
        self.leave3 = self.env['resource.calendar.leaves'].create({
            'name': 'ResourceLeave2',
            'calendar_id': self.calendar.id,
            'resource_id': self.resource1_id,
            'date_from': Datetime.from_string('2013-02-25 13:00:00'),
            'date_to': Datetime.from_string('2013-03-01 11:30:00')})
Example #57
0
    def test_30_calendar_working_days(self):
        """ Testing calendar hours computation on a working day """

        # Test: day1, beginning at 10:30 -> work from 10:30 (arrival) until 16:00
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=10, minute=30, second=0))
        self.assertEqual(
            len(intervals), 1,
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[0][0], Datetime.from_string('2013-02-12 10:30:00'),
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[0][1], Datetime.from_string('2013-02-12 16:00:00'),
            'resource_calendar: wrong working interval / day computing')
        # Test: hour computation for same interval, should give 5.5
        wh = self.calendar.get_working_hours_of_date(
            start_dt=self.date1.replace(hour=10, minute=30, second=0))
        self.assertEqual(
            wh, 5.5,
            'resource_calendar: wrong working interval / day time computing')

        # Test: day1+7 on leave, without leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) +
            relativedelta(days=7))
        # Result: day1 (08->16)
        self.assertEqual(
            len(intervals), 1,
            'resource_calendar: wrong working interval/day computing')
        self.assertEqual(
            intervals[0][0], Datetime.from_string('2013-02-19 08:00:00'),
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[0][1], Datetime.from_string('2013-02-19 16:00:00'),
            'resource_calendar: wrong working interval / day computing')

        # Test: day1+7 on leave, with generic leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) +
            relativedelta(days=7),
            compute_leaves=True)
        # Result: day1 (08->09 + 12->16)
        self.assertEqual(
            len(intervals), 2,
            'resource_calendar: wrong working interval/day computing')
        self.assertEqual(
            intervals[0][0], Datetime.from_string('2013-02-19 08:00:00'),
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[0][1], Datetime.from_string('2013-02-19 09:00:00'),
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[1][0], Datetime.from_string('2013-02-19 12:00:00'),
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[1][1], Datetime.from_string('2013-02-19 16:00:00'),
            'resource_calendar: wrong working interval / day computing')

        # Test: day1+14 on leave, with generic leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) +
            relativedelta(days=14),
            compute_leaves=True)
        # Result: day1 (08->16)
        self.assertEqual(
            len(intervals), 1,
            'resource_calendar: wrong working interval/day computing')
        self.assertEqual(
            intervals[0][0], Datetime.from_string('2013-02-26 08:00:00'),
            'resource_calendar: wrong working interval / day computing')
        self.assertEqual(
            intervals[0][1], Datetime.from_string('2013-02-26 16:00:00'),
            'resource_calendar: wrong working interval / day computing')

        # Test: day1+14 on leave, with resource leave computation
        intervals = self.calendar.get_working_intervals_of_day(
            start_dt=self.date1.replace(hour=7, minute=0, second=0) +
            relativedelta(days=14),
            compute_leaves=True,
            resource_id=self.resource1_id)
        # Result: nothing, because on leave
        self.assertEqual(
            len(intervals), 0,
            'resource_calendar: wrong working interval/day computing')
Example #58
0
 def _get_acquisition_date(self):
     self.ensure_one()
     return babel.dates.format_date(
         date=Datetime.from_string(self.acquisition_date),
         format='MMMM y',
         locale=self._context.get('lang') or 'en_US')
Example #59
0
 def setUpClass(cls):
     super(TestLeadConvert, cls).setUpClass()
     date = Datetime.from_string('2020-01-20 16:00:00')
     cls.crm_lead_dt_mock.now.return_value = date
Example #60
0
 def test_07(self):
     """After 182 days, exactly half of the budget line"""
     date = Datetime.to_string(Datetime.from_string('2014-07-02 00:00:00'))
     self.mock_datetime.now.return_value = date
     self.assertAlmostEqual(self.line.theoretical_amount, -182)