Пример #1
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')))
Пример #2
0
    def _interval_dates(self, frequency, company):
        """
        Method used to compute the theoretical date from which account move lines should be fetched
        @param {string} frequency: a valid value of the selection field on the object (daily, monthly, annually)
            frequencies are literal (daily means 24 hours and so on)
        @param {recordset} company: the company for which the closing is done
        @return {dict} the theoretical date from which account move lines are fetched.
            date_stop date to which the move lines are fetched, always now()
            the dates are in their Odoo Database string representation
        """
        date_stop = datetime.utcnow()
        interval_from = None
        name_interval = ''
        if frequency == 'daily':
            interval_from = date_stop - timedelta(days=1)
            name_interval = _('Daily Closing')
        elif frequency == 'monthly':
            month_target = date_stop.month > 1 and date_stop.month - 1 or 12
            year_target = month_target < 12 and date_stop.year or date_stop.year - 1
            interval_from = date_stop.replace(year=year_target, month=month_target)
            name_interval = _('Monthly Closing')
        elif frequency == 'annually':
            year_target = date_stop.year - 1
            interval_from = date_stop.replace(year=year_target)
            name_interval = _('Annual Closing')

        return {'interval_from': FieldDateTime.to_string(interval_from),
                'date_stop': FieldDateTime.to_string(date_stop),
                'name_interval': name_interval}
    def _send_sms_notification(self, params, send_mode='direct'):
        uuid = 'uid-1232389'
        params.update({
            'instance': 'test',
            'sender': '+41414104141',
            'operator': 'orange',
            'command': 'FORWARD',
            'date': Datetime.now(),
            'uuid': uuid,
        })
        if send_mode != 'direct':
            params.update({
                'receptionDate': Datetime.now(),
                'requestUid': uuid,
            })
            url_params = urllib.urlencode(params)
            response = self.url_open('/sms/mnc/?' + url_params)
            response_str = response.read()
            return response_str

        notification = self.env['sms.notification'].create(params)
        self.assertEqual(notification.state, 'new')
        response = notification.run_service()
        response_str = response.data
        self.assertEqual(notification.answer, response_str)
        return notification
Пример #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))
Пример #5
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")
Пример #6
0
    def test_in_date_5(self):
        """ Receive the same lot at different times, once they're in the same location, the quants
        are merged and only the earliest incoming date is kept.
        """
        lot1 = self.env['stock.production.lot'].create({
            'name': 'lot1',
            'product_id': self.product_lot.id,
        })

        from odoo.fields import Datetime
        in_date1 = Datetime.now()
        self.env['stock.quant']._update_available_quantity(self.product_lot, self.stock_location, 1.0, lot_id=lot1, in_date=in_date1)

        quant = self.env['stock.quant'].search([
            ('product_id', '=', self.product_lot.id),
            ('location_id', '=', self.stock_location.id),
        ])
        self.assertEqual(len(quant), 1)
        self.assertEqual(quant.quantity, 1)
        self.assertEqual(quant.lot_id.id, lot1.id)
        self.assertEqual(quant.in_date, in_date1)

        in_date2 = Datetime.now() - timedelta(days=5)
        self.env['stock.quant']._update_available_quantity(self.product_lot, self.stock_location, 1.0, lot_id=lot1, in_date=in_date2)

        quant = self.env['stock.quant'].search([
            ('product_id', '=', self.product_lot.id),
            ('location_id', '=', self.stock_location.id),
        ])
        self.assertEqual(len(quant), 1)
        self.assertEqual(quant.quantity, 2)
        self.assertEqual(quant.lot_id.id, lot1.id)
        self.assertEqual(quant.in_date, in_date2)
Пример #7
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
Пример #8
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)
Пример #9
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')))
Пример #10
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')))
Пример #11
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')))
Пример #12
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)
Пример #13
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)
Пример #14
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')))
Пример #15
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)
Пример #16
0
 def poll(self, channels, last, options=None):
     if request.env.user.has_group('base.group_user'):
         ip_address = request.httprequest.remote_addr
         users_log = request.env['res.users.log'].search_count([
             ('create_uid', '=', request.env.user.id),
             ('ip', '=', ip_address),
             ('create_date', '>=', Datetime.to_string(Datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)))])
         if not users_log:
             with registry(request.env.cr.dbname).cursor() as cr:
                 env = Environment(cr, request.env.user.id, {})
                 env['res.users.log'].create({'ip': ip_address})
     return super(BusController, self).poll(channels, last, options=options)
Пример #17
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')
Пример #18
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')))
Пример #19
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)
Пример #20
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
Пример #21
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)
Пример #22
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'
     )
Пример #23
0
    def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
        res = super(StockHistory, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
        if 'inventory_value' in fields:
            date = self._context.get('history_date', fieldsDatetime.now())
            stock_history = self.env['stock.history']
            group_lines = {}
            for line in res:
                domain = line.get('__domain', domain)
                group_lines.setdefault(str(domain), self.search(domain))
                stock_history |= group_lines[str(domain)]

            histories_dict = {}
            not_real_cost_method_products = stock_history.mapped('product_id').filtered(lambda product: product.cost_method != 'real')
            if not_real_cost_method_products:
                self._cr.execute("""SELECT DISTINCT ON (product_id, company_id) product_id, company_id, cost
                    FROM product_price_history
                    WHERE product_id in %s AND datetime <= %s
                    ORDER BY product_id, company_id, datetime DESC, id DESC""", (tuple(not_real_cost_method_products.ids), date))
                for history in self._cr.dictfetchall():
                    histories_dict[(history['product_id'], history['company_id'])] = history['cost']

            for line in res:
                inv_value = 0.0
                for stock_history in group_lines.get(str(line.get('__domain', domain))):
                    product = stock_history.product_id
                    if product.cost_method == 'real':
                        price = stock_history.price_unit_on_quant
                    else:
                        price = histories_dict.get((product.id, stock_history.company_id.id), 0.0)
                    inv_value += price * stock_history.quantity
                line['inventory_value'] = inv_value

        return res
Пример #24
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')))
Пример #25
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')
Пример #26
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')))
Пример #27
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)
Пример #28
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')
Пример #29
0
    def test_event_date_range(self):
        self.patcher = patch('odoo.addons.event.models.event.fields.Datetime', wraps=Datetime)
        self.mock_datetime = self.patcher.start()

        self.mock_datetime.now.return_value = Datetime.to_string(datetime.datetime(2015, 12, 31, 12, 0))

        self.event_0.registration_ids.event_begin_date = datetime.datetime(2015, 12, 31, 18, 0)
        self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'today')

        self.event_0.registration_ids.event_begin_date = datetime.datetime(2016, 1, 1, 6, 0)
        self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'tomorrow')

        self.event_0.registration_ids.event_begin_date = datetime.datetime(2016, 1, 2, 6, 0)
        self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'in 2 days')

        self.mock_datetime.now.return_value = Datetime.to_string(datetime.datetime(2015, 12, 10, 12, 0))
        self.event_0.registration_ids.event_begin_date = datetime.datetime(2016, 1, 25, 6, 0)
        self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'next month')

        self.patcher.stop()
Пример #30
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)
Пример #31
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
Пример #32
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'))
Пример #33
0
    def test_basic(self):
        """ Basic order test: no routing (thus no workorders), no lot """
        self.product_1.type = 'product'
        self.product_2.type = 'product'
        inventory = self.env['stock.inventory'].create({
            'name':
            'Initial inventory',
            'filter':
            'partial',
            'line_ids': [(0, 0, {
                'product_id': self.product_1.id,
                'product_uom_id': self.product_1.uom_id.id,
                'product_qty': 500,
                'location_id': self.warehouse_1.lot_stock_id.id
            }),
                         (0, 0, {
                             'product_id': self.product_2.id,
                             'product_uom_id': self.product_2.uom_id.id,
                             'product_qty': 500,
                             'location_id': self.warehouse_1.lot_stock_id.id
                         })]
        })
        inventory.action_validate()

        test_date_planned = Dt.now() - timedelta(days=1)
        test_quantity = 2.0
        self.bom_1.routing_id = False
        man_order = self.env['mrp.production'].sudo(self.user_mrp_user).create(
            {
                'name': 'Stick-0',
                'product_id': self.product_4.id,
                'product_uom_id': self.product_4.uom_id.id,
                'product_qty': test_quantity,
                'bom_id': self.bom_1.id,
                'date_planned_start': test_date_planned,
                'location_src_id': self.location_1.id,
                'location_dest_id': self.warehouse_1.wh_output_stock_loc_id.id,
            })
        self.assertEqual(man_order.state, 'confirmed',
                         "Production order should be in confirmed state.")

        # check production move
        production_move = man_order.move_finished_ids
        self.assertEqual(production_move.date, test_date_planned)
        self.assertEqual(production_move.product_id, self.product_4)
        self.assertEqual(production_move.product_uom, man_order.product_uom_id)
        self.assertEqual(production_move.product_qty, man_order.product_qty)
        self.assertEqual(production_move.location_id,
                         self.product_4.property_stock_production)
        self.assertEqual(production_move.location_dest_id,
                         man_order.location_dest_id)

        # check consumption moves
        for move in man_order.move_raw_ids:
            self.assertEqual(move.date, test_date_planned)
        first_move = man_order.move_raw_ids.filtered(
            lambda move: move.product_id == self.product_2)
        self.assertEqual(
            first_move.product_qty, test_quantity / self.bom_1.product_qty *
            self.product_4.uom_id.factor_inv * 2)
        first_move = man_order.move_raw_ids.filtered(
            lambda move: move.product_id == self.product_1)
        self.assertEqual(
            first_move.product_qty, test_quantity / self.bom_1.product_qty *
            self.product_4.uom_id.factor_inv * 4)

        # waste some material, create a scrap
        # scrap = self.env['stock.scrap'].with_context(
        #     active_model='mrp.production', active_id=man_order.id
        # ).create({})
        # scrap = self.env['stock.scrap'].create({
        #     'production_id': man_order.id,
        #     'product_id': first_move.product_id.id,
        #     'product_uom_id': first_move.product_uom.id,
        #     'scrap_qty': 5.0,
        # })
        # check created scrap

        # procurements = self.env['procurement.order'].search([('move_dest_id', 'in', man_order.move_raw_ids.ids)])
        # print procurements
        # procurements = self.env['procurement.order'].search([('production_id', '=', man_order.id)])
        # print procurements
        # for proc in self.env['procurement.order'].browse(procurements):
        #     date_planned = self.mrp_production_test1.date_planned
        #     if proc.product_id.type not in ('product', 'consu'):
        #         continue
        #     if proc.product_id.id == order_line.product_id.id:
        #         self.assertEqual(proc.date_planned, date_planned, "Planned date does not correspond")
        #       # procurement state should be `confirmed` at this stage, except if procurement_jit is installed, in which
        #       # case it could already be in `running` or `exception` state (not enough stock)
        #         expected_states = ('confirmed', 'running', 'exception')
        #         self.assertEqual(proc.state in expected_states, 'Procurement state is `%s` for %s, expected one of %s' % (proc.state, proc.product_id.name, expected_states))

        # Change production quantity
        qty_wizard = self.env['change.production.qty'].create({
            'mo_id':
            man_order.id,
            'product_qty':
            3.0,
        })
        # qty_wizard.change_prod_qty()

        # # I check qty after changed in production order.
        # #self.assertEqual(self.mrp_production_test1.product_qty, 3, "Qty is not changed in order.")
        # move = self.mrp_production_test1.move_finished_ids[0]
        # self.assertEqual(move.product_qty, self.mrp_production_test1.product_qty, "Qty is not changed in move line.")

        # # I run scheduler.
        # self.env['procurement.order'].run_scheduler()

        # # The production order is Waiting Goods, will force production which should set consume lines as available
        # self.mrp_production_test1.button_plan()
        # # I check that production order in ready state after forcing production.

        # #self.assertEqual(self.mrp_production_test1.availability, 'assigned', 'Production order availability should be set as available')

        # produce product
        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id':
            man_order.id,
            'active_ids': [man_order.id],
        }))
        produce_form.product_qty = 1.0
        produce_wizard = produce_form.save()
        produce_wizard.do_produce()

        # man_order.button_mark_done()
        man_order.button_mark_done()
        self.assertEqual(man_order.state, 'done',
                         "Production order should be in done state.")
Пример #34
0
    def test_event_configuration_from_type(self):
        """ Test data computation of event coming from its event.type template.
        Some one2many notably are duplicated from type configuration and some
        advanced testing is required, notably mail schedulers. """

        self.assertEqual(self.env.user.tz, 'Europe/Brussels')

        event_type = self.event_type_complex.with_user(self.env.user)
        event_type.write({
            'use_mail_schedule': False,
        })
        # Event type does not use mail schedule but data is kept for compatibility and avoid recreating them
        self.assertEqual(len(event_type.event_type_mail_ids), 2)

        event = self.env['event.event'].create({
            'name':
            'Event Update Type',
            'date_begin':
            FieldsDatetime.to_string(datetime.today() + timedelta(days=1)),
            'date_end':
            FieldsDatetime.to_string(datetime.today() + timedelta(days=15)),
            'auto_confirm':
            False,
            'is_online':
            True,
        })
        self.assertEqual(event.date_tz, self.env.user.tz)
        self.assertEqual(event.seats_availability, 'unlimited')
        self.assertFalse(event.auto_confirm)
        self.assertTrue(event.is_online)
        self.assertEqual(event.event_mail_ids, self.env['event.mail'])

        event.update({'event_type_id': event_type.id})
        event._onchange_type()
        self.assertEqual(event.date_tz, 'Europe/Paris')
        self.assertEqual(event.seats_availability, 'limited')
        self.assertEqual(event.seats_max, event_type.default_registration_max)
        self.assertTrue(event.auto_confirm)
        self.assertFalse(event.is_online)
        self.assertEqual(event.event_mail_ids, self.env['event.mail'])

        event_type.write({
            'use_mail_schedule':
            True,
            'event_type_mail_ids':
            [(5, 0),
             (0, 0, {
                 'interval_nbr':
                 1,
                 'interval_unit':
                 'days',
                 'interval_type':
                 'before_event',
                 'template_id':
                 self.env['ir.model.data'].xmlid_to_res_id(
                     'event.event_reminder')
             })]
        })
        event._onchange_type()
        self.assertEqual(event.event_mail_ids.interval_nbr, 1)
        self.assertEqual(event.event_mail_ids.interval_unit, 'days')
        self.assertEqual(event.event_mail_ids.interval_type, 'before_event')
        self.assertEqual(event.event_mail_ids.template_id,
                         self.env.ref('event.event_reminder'))
    def _get_report_data(self, data):
        year = data['year']
        employees = self.env['hr.employee'].browse(data['employee_ids'])

        payslips = self.env['hr.payslip'].search([
            ('employee_id', 'in', employees.ids),
            ('state', '=', 'done'),
            ('date_from', '>=', Datetime.now().replace(month=1,
                                                       day=1,
                                                       year=year)),
            ('date_from', '<=', Datetime.now().replace(month=12,
                                                       day=31,
                                                       year=year)),
            '|',
            ('struct_id.country_id', '=', False),
            ('struct_id.country_id', '=', self.env.ref('base.be').id),
        ])
        lines = payslips.mapped('line_ids')
        payslip_rules = [(rule.code, rule.sequence)
                         for rule in lines.mapped('salary_rule_id')]
        payslip_rules = sorted(payslip_rules, key=lambda x: x[1])
        worked_days = payslips.mapped('worked_days_line_ids')

        result = {
            employee: {
                'rules':
                OrderedDict((rule[0], {
                    'year': {
                        'name': False,
                        'total': 0
                    },
                    'month':
                    {m: {
                        'name': False,
                        'total': 0
                    }
                     for m in range(12)},
                    'quarter':
                    {q: {
                        'name': False,
                        'total': 0
                    }
                     for q in range(4)}
                }) for rule in payslip_rules),
                'worked_days': {
                    code: {
                        'year': {
                            'name': False,
                            'number_of_days': 0,
                            'number_of_hours': 0
                        },
                        'month': {
                            m: {
                                'name': False,
                                'number_of_days': 0,
                                'number_of_hours': 0
                            }
                            for m in range(12)
                        },
                        'quarter': {
                            q: {
                                'name': False,
                                'number_of_days': 0,
                                'number_of_hours': 0
                            }
                            for q in range(4)
                        }
                    }
                    for code in worked_days.mapped('code')
                }
            }
            for employee in employees
        }

        for line in lines:
            rule = result[line.employee_id]['rules'][line.salary_rule_id.code]
            month = line.slip_id.date_from.month - 1
            rule['month'][month]['name'] = line.name
            rule['month'][month]['total'] += line.total
            rule['quarter'][(month) // 3]['name'] = line.name
            rule['quarter'][(month) // 3]['total'] += line.total
            rule['year']['name'] = line.name
            rule['year']['total'] += line.total

            rule['month'][month]['total'] = round(
                rule['month'][month]['total'], 2)
            rule['quarter'][(month) // 3]['total'] = round(
                rule['quarter'][(month) // 3]['total'], 2)
            rule['year']['total'] = round(rule['year']['total'], 2)

        for worked_day in worked_days:
            work = result[worked_day.payslip_id.employee_id]['worked_days'][
                worked_day.code]
            month = worked_day.payslip_id.date_from.month - 1

            work['month'][month]['name'] = worked_day.name
            work['month'][month]['number_of_days'] += worked_day.number_of_days
            work['month'][month][
                'number_of_hours'] += worked_day.number_of_hours
            work['quarter'][(month) // 3]['name'] = worked_day.name
            work['quarter'][(month) //
                            3]['number_of_days'] += worked_day.number_of_days
            work['quarter'][(month) //
                            3]['number_of_hours'] += worked_day.number_of_hours
            work['year']['name'] = worked_day.name
            work['year']['number_of_days'] += worked_day.number_of_days
            work['year']['number_of_hours'] += worked_day.number_of_hours

        return {'year': year, 'employee_data': result}
Пример #36
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()
Пример #37
0
    def test_merge_method_followers(self):
        """ Test that the followers of the leads are added in the destination lead.

        They should be added if:
        - The related partner was active on the lead (posted a message in the last 30 days)
        - The related partner is not already following the destination lead

        Leads                       Followers           Info
        ---------------------------------------------------------------------------------
        lead_w_contact              contact_1           OK (destination lead)
        lead_w_email                contact_1           KO (already following the destination lead)
                                    contact_2           OK (active on lead_w_email)
                                    contact_company     KO (most recent message on lead_w_email is 35 days ago, message
                                                            on lead_w_partner is not counted as he doesn't follow it)
        lead_w_partner              contact_2           KO (already added with lead_w_email)
        lead_w_partner_company
        """
        self.leads.message_follower_ids.unlink()
        self.leads.message_ids.unlink()

        self.lead_w_contact.message_subscribe([self.contact_1.id])
        self.lead_w_email.message_subscribe(
            [self.contact_1.id, self.contact_2.id, self.contact_company.id])
        self.lead_w_partner.message_subscribe([self.contact_2.id])

        self.env['mail.message'].create([{
            'author_id':
            self.contact_1.id,
            'model':
            'crm.lead',
            'res_id':
            self.lead_w_contact.id,
            'date':
            Datetime.now() - timedelta(days=1),
            'subtype_id':
            self.ref('mail.mt_comment'),
            'reply_to':
            False,
            'body':
            'Test follower',
        }, {
            'author_id':
            self.contact_1.id,
            'model':
            'crm.lead',
            'res_id':
            self.lead_w_email.id,
            'date':
            Datetime.now() - timedelta(days=20),
            'subtype_id':
            self.ref('mail.mt_comment'),
            'reply_to':
            False,
            'body':
            'Test follower',
        }, {
            'author_id':
            self.contact_2.id,
            'model':
            'crm.lead',
            'res_id':
            self.lead_w_email.id,
            'date':
            Datetime.now() - timedelta(days=15),
            'subtype_id':
            self.ref('mail.mt_comment'),
            'reply_to':
            False,
            'body':
            'Test follower',
        }, {
            'author_id':
            self.contact_2.id,
            'model':
            'crm.lead',
            'res_id':
            self.lead_w_partner.id,
            'date':
            Datetime.now() - timedelta(days=29),
            'subtype_id':
            self.ref('mail.mt_comment'),
            'reply_to':
            False,
            'body':
            'Test follower',
        }, {
            'author_id':
            self.contact_company.id,
            'model':
            'crm.lead',
            'res_id':
            self.lead_w_email.id,
            'date':
            Datetime.now() - timedelta(days=35),
            'subtype_id':
            self.ref('mail.mt_comment'),
            'reply_to':
            False,
            'body':
            'Test follower',
        }, {
            'author_id':
            self.contact_company.id,
            'model':
            'crm.lead',
            'res_id':
            self.lead_w_partner.id,
            'date':
            Datetime.now(),
            'subtype_id':
            self.ref('mail.mt_comment'),
            'reply_to':
            False,
            'body':
            'Test follower',
        }])
        initial_followers = self.lead_w_contact.message_follower_ids

        leads = self.env['crm.lead'].browse(
            self.leads.ids)._sort_by_confidence_level(reverse=True)
        master_lead = leads._merge_opportunity(max_length=None)

        self.assertEqual(master_lead, self.lead_w_contact)

        # Check followers of the destination lead
        new_partner_followers = (master_lead.message_follower_ids -
                                 initial_followers).partner_id
        self.assertIn(self.contact_2, new_partner_followers,
                      'The partner must follow the destination lead')
        # "contact_company" posted a message 35 days ago on lead_2, so it's considered as inactive
        # "contact_company" posted a message now on lead_3, but he doesn't follow lead_3
        # so this message is just ignored
        self.assertNotIn(self.contact_company, new_partner_followers,
                         'The partner was not active on the lead')
        self.assertIn(
            self.contact_1, master_lead.message_follower_ids.partner_id,
            'Should not have removed follower of the destination lead')
Пример #38
0
    def setUp(self):
        super(TestMailActivityTeam, self).setUp()

        self.env["mail.activity.team"].search([]).unlink()

        self.employee = self.env['res.users'].create({
            'company_id':
            self.env.ref("base.main_company").id,
            'name':
            "Employee",
            'login':
            "******",
            'email':
            "*****@*****.**",
            'groups_id': [(6, 0, [
                self.env.ref('base.group_user').id,
                self.env.ref('base.group_partner_manager').id
            ])]
        })

        self.employee2 = self.env['res.users'].create({
            'company_id':
            self.env.ref("base.main_company").id,
            'name':
            "Employee 2",
            'login':
            "******",
            'email':
            "*****@*****.**",
            'groups_id': [(6, 0, [self.env.ref('base.group_user').id])]
        })

        self.partner_ir_model = self.env['ir.model']._get('res.partner')

        activity_type_model = self.env['mail.activity.type']
        self.activity1 = activity_type_model.create({
            'name':
            'Initial Contact',
            'days':
            5,
            'summary':
            'ACT 1 : Presentation, barbecue, ... ',
            'res_model_id':
            self.partner_ir_model.id,
        })
        self.activity2 = activity_type_model.create({
            'name':
            'Call for Demo',
            'days':
            6,
            'summary':
            'ACT 2 : I want to show you my ERP !',
            'res_model_id':
            self.partner_ir_model.id,
        })

        self.partner_client = self.env.ref("base.res_partner_1")

        self.act1 = self.env['mail.activity'].sudo(self.employee).create({
            'activity_type_id':
            self.activity1.id,
            'note':
            'Partner activity 1.',
            'res_id':
            self.partner_client.id,
            'res_model_id':
            self.partner_ir_model.id,
            'user_id':
            self.employee.id,
        })

        self.team1 = self.env['mail.activity.team'].sudo().create({
            'name':
            'Team 1',
            'res_model_ids': [(6, 0, [self.partner_ir_model.id])],
            'member_ids': [(6, 0, [self.employee.id])],
        })

        self.team2 = self.env['mail.activity.team'].sudo().create({
            'name':
            'Team 2',
            'res_model_ids': [(6, 0, [self.partner_ir_model.id])],
            'member_ids': [(6, 0, [self.employee.id, self.employee2.id])],
        })

        self.act2 = self.env['mail.activity'].sudo(self.employee).create({
            'activity_type_id':
            self.activity2.id,
            'note':
            'Partner activity 2.',
            'res_id':
            self.partner_client.id,
            'res_model_id':
            self.partner_ir_model.id,
            'user_id':
            self.employee.id,
        })

        self.act3 = self.env['mail.activity'].sudo(self.employee).create({
            'activity_type_id':
            self.browse_ref('mail.mail_activity_data_meeting').id,
            'note':
            'Meeting activity 3.',
            'res_id':
            self.partner_client.id,
            'res_model_id':
            self.partner_ir_model.id,
            'user_id':
            self.employee.id,
            'team_id':
            self.team1.id,
            'summary':
            'Metting activity'
        })
        self.start = Datetime.now()
        self.stop = Datetime.to_string(
            Datetime.from_string(self.start) + timedelta(hours=1))
    def setUpClass(cls):
        super(TestTimesheetTimer, cls).setUpClass()

        User = cls.env['res.users'].with_context({'no_reset_password': True})
        Factor = cls.env['hr_timesheet_invoice.factor']
        Task = cls.env['project.task']
        Timesheet = cls.env['account.analytic.line']
        Project = cls.env['project.project']

        user_group_employee = cls.env.ref('base.group_user')
        user_group_project_user = cls.env.ref('project.group_project_user')
        groups = [user_group_employee.id, user_group_project_user.id]

        cls.user_projectuser = User.create({
            'name': 'Armande ProjectUser',
            'login': '******',
            'email': '*****@*****.**',
            'groups_id': [(6, 0, groups)]
        })

        cls.no_discount = Factor.create({
            'name': 'No Discount',
            'factor': 0.0,
        })

        cls.full_discount = Factor.create({
            'name': 'Full Discount',
            'factor': 100.0,
        })

        cls.partner_1 = cls.env['res.partner'].create({
            'name': 'Bill Smith',
            'email': '*****@*****.**',
            'notify_email': 'always',
        })

        cls.api_project = Project.create({
            'name': 'Timed Project',
            'partner_id': cls.partner_1.id,
        })

        cls.task = Task.create({
            'name': 'Bill for this work',
            'partner_id': cls.partner_1.id,
            'project_id': cls.api_project.id,
        })

        # timesheet with 15 minutes on previous Start/Pause instance
        # and 15 minutes on the current instance
        Timesheet.create({
            'name':
            'Worked on this briefly',
            'date_start':
            Datetime.to_string(datetime.now() - timedelta(minutes=15)),
            'user_id':
            cls.user_projectuser.id,
            'task_id':
            cls.task.id,
            'project_id':
            cls.api_project.id,
            'factor':
            cls.no_discount.id,
            'timer_status':
            'stopped',
            'amount':
            40,
            'full_duration':
            .25,
            'unit_amount':
            .25,
        })
Пример #40
0
    def setUp(self):
        super(TestUICommon, self).setUp()
        # Load pdf and img contents
        pdf_path = get_module_resource('website_slides', 'static', 'src', 'img', 'presentation.pdf')
        pdf_content = base64.b64encode(open(pdf_path, "rb").read())
        img_path = get_module_resource('website_slides', 'static', 'src', 'img', 'slide_demo_gardening_1.jpg')
        img_content = base64.b64encode(open(img_path, "rb").read())

        self.env['slide.channel'].create({
            'name': 'Basics of Gardening - Test',
            'user_id': self.env.ref('base.user_admin').id,
            'enroll': 'public',
            'channel_type': 'training',
            'allow_comment': True,
            'promote_strategy': 'most_voted',
            'is_published': True,
            'description': 'Learn the basics of gardening !',
            'create_date': Datetime.now() - relativedelta(days=8),
            'slide_ids': [
                (0, 0, {
                    'name': 'Gardening: The Know-How',
                    'sequence': 1,
                    'datas': pdf_content,
                    'slide_type': 'presentation',
                    'is_published': True,
                    'is_preview': True,
                }), (0, 0, {
                    'name': 'Home Gardening',
                    'sequence': 2,
                    'image_1920': img_content,
                    'slide_type': 'infographic',
                    'is_published': True,
                }), (0, 0, {
                    'name': 'Mighty Carrots',
                    'sequence': 3,
                    'image_1920': img_content,
                    'slide_type': 'infographic',
                    'is_published': True,
                }), (0, 0, {
                    'name': 'How to Grow and Harvest The Best Strawberries | Basics',
                    'sequence': 4,
                    'datas': pdf_content,
                    'slide_type': 'document',
                    'is_published': True,
                }), (0, 0, {
                    'name': 'Test your knowledge',
                    'sequence': 5,
                    'slide_type': 'quiz',
                    'is_published': True,
                    'question_ids': [
                        (0, 0, {
                            'question': 'What is a strawberry ?',
                            'answer_ids': [
                                (0, 0, {
                                    'text_value': 'A fruit',
                                    'is_correct': True,
                                    'sequence': 1,
                                }), (0, 0, {
                                    'text_value': 'A vegetable',
                                    'sequence': 2,
                                }), (0, 0, {
                                    'text_value': 'A table',
                                    'sequence': 3,
                                })
                            ]
                        }), (0, 0, {
                            'question': 'What is the best tool to dig a hole for your plants ?',
                            'answer_ids': [
                                (0, 0, {
                                    'text_value': 'A shovel',
                                    'is_correct': True,
                                    'sequence': 1,
                                }), (0, 0, {
                                    'text_value': 'A spoon',
                                    'sequence': 2,
                                })
                            ]
                        })
                    ]
                })
            ]
        })
Пример #41
0
    def _check_presence(self):
        company = self.env.company
        if not company.hr_presence_last_compute_date or \
                company.hr_presence_last_compute_date.day != Datetime.now().day:
            self.env['hr.employee'].search([
                ('department_id.company_id', '=', company.id)
            ]).write({'hr_presence_state': 'to_define'})

        employees = self.env['hr.employee'].search([
            ('department_id.company_id', '=', company.id),
            ('user_id', '!=', False), ('hr_presence_state', '=', 'to_define')
        ])

        # Remove employees on holidays
        leaves = self.env['hr.leave'].search([
            ('state', '=', 'validate'),
            ('date_from', '<=', Datetime.to_string(Datetime.now())),
            ('date_to', '>=', Datetime.to_string(Datetime.now()))
        ])
        employees_on_holiday = leaves.mapped('employee_id')
        employees_on_holiday.write({'hr_presence_state': 'absent'})
        employees = employees - employees_on_holiday

        # Check on system login
        if self.env['ir.config_parameter'].sudo().get_param(
                'hr_presence.hr_presence_control_login'):
            online_employees = employees.filtered(
                lambda employee: employee.user_id.im_status in
                ['away', 'online'])
            online_employees.write({'hr_presence_state': 'present'})
            employees = employees - online_employees

        # Check on IP
        if self.env['ir.config_parameter'].sudo().get_param(
                'hr_presence.hr_presence_control_ip'):
            ip_list = company.hr_presence_control_ip_list
            ip_list = ip_list.split(',') if ip_list else []
            ip_employees = self.env['hr.employee']
            for employee in employees:
                employee_ips = self.env['res.users.log'].search([
                    ('create_uid', '=', employee.user_id.id),
                    ('ip', '!=', False),
                    ('create_date', '>=',
                     Datetime.to_string(Datetime.now().replace(hour=0,
                                                               minute=0,
                                                               second=0,
                                                               microsecond=0)))
                ]).mapped('ip')
                if any([ip in ip_list for ip in employee_ips]):
                    ip_employees |= employee
            ip_employees.write({'hr_presence_state': 'present'})
            employees = employees - ip_employees

        # Check on sent emails
        if self.env['ir.config_parameter'].sudo().get_param(
                'hr_presence.hr_presence_control_email'):
            email_employees = self.env['hr.employee']
            threshold = company.hr_presence_control_email_amount
            for employee in employees:
                sent_emails = self.env['mail.message'].search_count([
                    ('author_id', '=', employee.user_id.partner_id.id),
                    ('date', '>=',
                     Datetime.to_string(Datetime.now().replace(
                         hour=0, minute=0, second=0, microsecond=0))),
                    ('date', '<=', Datetime.to_string(Datetime.now()))
                ])
                if sent_emails >= threshold:
                    email_employees |= employee
            email_employees.write({'hr_presence_state': 'present'})
            employees = employees - email_employees

        company.hr_presence_last_compute_date = Datetime.now()
    def setUpClass(cls):
        super(TestMailActivityTeam, cls).setUpClass()
        cls.env = cls.env(context=dict(
            cls.env.context, tracking_disable=True, no_reset_password=True))
        cls.env["mail.activity.team"].search([]).unlink()

        cls.employee = cls.env['res.users'].create({
            'company_id':
            cls.env.ref("base.main_company").id,
            'name':
            "Employee",
            'login':
            "******",
            'email':
            "*****@*****.**",
            'groups_id': [(6, 0, [
                cls.env.ref('base.group_user').id,
                cls.env.ref('base.group_partner_manager').id
            ])]
        })

        cls.employee2 = cls.env['res.users'].create({
            'company_id':
            cls.env.ref("base.main_company").id,
            'name':
            "Employee 2",
            'login':
            "******",
            'email':
            "*****@*****.**",
            'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])]
        })

        cls.partner_ir_model = cls.env['ir.model']._get('res.partner')

        activity_type_model = cls.env['mail.activity.type']
        cls.activity1 = activity_type_model.create({
            'name':
            'Initial Contact',
            'summary':
            'ACT 1 : Presentation, barbecue, ... ',
            'res_model_id':
            cls.partner_ir_model.id,
        })
        cls.activity2 = activity_type_model.create({
            'name':
            'Call for Demo',
            'summary':
            'ACT 2 : I want to show you my ERP !',
            'res_model_id':
            cls.partner_ir_model.id,
        })

        cls.partner_client = cls.env.ref("base.res_partner_1")

        cls.act1 = cls.env['mail.activity'].sudo(cls.employee).create({
            'activity_type_id':
            cls.activity1.id,
            'note':
            'Partner activity 1.',
            'res_id':
            cls.partner_client.id,
            'res_model_id':
            cls.partner_ir_model.id,
            'user_id':
            cls.employee.id,
        })

        cls.team1 = cls.env['mail.activity.team'].sudo().create({
            'name':
            'Team 1',
            'res_model_ids': [(6, 0, [cls.partner_ir_model.id])],
            'member_ids': [(6, 0, [cls.employee.id])],
        })

        cls.team2 = cls.env['mail.activity.team'].sudo().create({
            'name':
            'Team 2',
            'res_model_ids': [(6, 0, [cls.partner_ir_model.id])],
            'member_ids': [(6, 0, [cls.employee.id, cls.employee2.id])],
        })

        cls.act2 = cls.env['mail.activity'].sudo(cls.employee).create({
            'activity_type_id':
            cls.activity2.id,
            'note':
            'Partner activity 2.',
            'res_id':
            cls.partner_client.id,
            'res_model_id':
            cls.partner_ir_model.id,
            'user_id':
            cls.employee.id,
        })

        cls.act3 = cls.env['mail.activity'].sudo(cls.employee).create({
            'activity_type_id':
            cls.env.ref('mail.mail_activity_data_meeting').id,
            'note':
            'Meeting activity 3.',
            'res_id':
            cls.partner_client.id,
            'res_model_id':
            cls.partner_ir_model.id,
            'user_id':
            cls.employee.id,
            'team_id':
            cls.team1.id,
            'summary':
            'Metting activity'
        })
        cls.start = Datetime.now()
        cls.stop = Datetime.to_string(
            Datetime.from_string(cls.start) + timedelta(hours=1))
Пример #43
0
def read_group(self,
               domain,
               fields,
               groupby,
               offset=0,
               limit=None,
               orderby=False,
               lazy=True):
    # Step 1: retrieve the standard read_group output. In case of inventory valuation, this
    # will be mostly used as a 'skeleton' since the inventory value needs to be computed based
    # on the individual lines.
    res = super(StockHistory, self).read_group(domain,
                                               fields,
                                               groupby,
                                               offset=offset,
                                               limit=limit,
                                               orderby=orderby,
                                               lazy=lazy)
    if "inventory_value" in fields:
        groupby_list = groupby[:1] if lazy else groupby
        date = self._context.get("history_date", fieldsDatetime.now())

        # Step 2: retrieve the stock history lines. The result contains the 'expanded'
        # version of the read_group. We build the query manually for performance reason
        # (and avoid a costly 'WHERE id IN ...').
        fields_2 = set([
            "id", "product_id", "price_unit_on_quant", "company_id", "quantity"
        ] + groupby_list)
        query = self._where_calc(domain)
        self._apply_ir_rules(query, "read")
        tables, where_clause, where_clause_params = query.get_sql()
        select = "SELECT %s FROM %s WHERE %s "
        query = select % (",".join(fields_2), tables, where_clause)
        self._cr.execute(query, where_clause_params)

        # Step 3: match the lines retrieved at step 2 with the aggregated results of step 1.
        # In other words, we link each item of the read_group result with the corresponding
        # lines.
        stock_history_data = {}
        stock_histories_by_group = {}
        for line in self._cr.dictfetchall():
            stock_history_data[line["id"]] = line
            key = tuple(line.get(g) or False for g in groupby_list)
            stock_histories_by_group.setdefault(key, [])
            stock_histories_by_group[key] += [line["id"]]

        histories_dict = {}
        # sudo() added here (QRTL)
        not_real_cost_method_products = (
            self.env["product.product"].sudo().browse(
                record["product_id"]
                for record in stock_history_data.values()).filtered(
                    lambda product: product.cost_method != "real"))
        if not_real_cost_method_products:
            self._cr.execute(
                """SELECT DISTINCT ON (product_id, company_id) product_id, company_id, cost
                FROM product_price_history
                WHERE product_id in %s AND datetime <= %s
                ORDER BY product_id, company_id, datetime DESC, id DESC""",
                (tuple(not_real_cost_method_products.ids), date),
            )
            for history in self._cr.dictfetchall():
                histories_dict[(history["product_id"],
                                history["company_id"])] = history["cost"]

        for line in res:
            inv_value = 0.0
            # Build the same keys than above, but need to take into account Many2one are tuples
            key = tuple(line[g] if g in line else False for g in groupby_list)
            key = tuple(k[0] if isinstance(k, tuple) else k for k in key)
            for stock_history in self.env["stock.history"].browse(
                    stock_histories_by_group[key]):
                history_data = stock_history_data[stock_history.id]
                product_id = history_data["product_id"]
                if self.env["product.product"].browse(
                        product_id).cost_method == "real":
                    price = history_data["price_unit_on_quant"]
                else:
                    price = histories_dict.get(
                        (product_id, history_data["company_id"]), 0.0)
                inv_value += price * history_data["quantity"]
            line["inventory_value"] = inv_value

    return res
Пример #44
0
    def generate_xlsx_report(self, workbook, data, attendances):
        row = 1

        # Setup sheet and data
        report_name = datetime.today().strftime(
            "%Y-%m-%d") + "DAILY ABSENCE REPORT"
        attendances = self.env['zk.machine.attendance'].search([])

        attendances = attendances.filtered(
            lambda attend: ODT.context_timestamp(
                attend, ODT.from_string(attend.punching_time)).strftime(
                    '%Y-%m-%d') == data['form']['date'])

        employees = self.env['hr.employee'].sudo().search([])
        employees = employees.filtered(
            lambda e: e.id not in attendances.mapped('employee_id.id'))
        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})
        t_heading = workbook.add_format({
            'align': 'center',
            'bold': True,
            'bg_color': '#BD5B5B',
            'border': 1
        })
        sheet.set_column('C:C', 35)
        sheet.set_column('D:D', 30)
        sheet.set_column('E:E', 35)

        # Headings and titles
        sheet.merge_range(0, 1, 0, 4, 'HR DEPARTMENT', titles)
        sheet.merge_range(1, 1, 1, 4, 'DAILY ABSENCE REPORT', titles)
        sheet.merge_range(3, 1, 3, 4, 'DATE : ' + data['form']['date'], titles)
        sheet.write_row('B6', ['Emp ID', 'Name', 'Job Title', 'Department'],
                        t_heading)

        for obj in employees:
            rgb_color = obj.department_id.color
            color = '#FFFFFF'
            if not rgb_color:
                rgb_color = "rgba(255,0,0,1)"
            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
            })
            sheet.write_row('B' + str(row + 6), [row], emp_id)
            sheet.write_row('C' + str(row + 6), [
                obj.name, obj.job_id.name or '-', obj.department_id.name or '-'
            ], attendance)
            row += 1
 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, self.date_planned)))
Пример #46
0
    def setUp(self):
        super().setUp()
        self.event_2 = self.env['event.event'].create({
            'name':
            'Conference for Architects TEST',
            'user_id':
            self.env.ref('base.user_admin').id,
            'date_begin': (Datetime.today() +
                           timedelta(days=5)).strftime('%Y-%m-%d 07:00:00'),
            'date_end': (Datetime.today() +
                         timedelta(days=5)).strftime('%Y-%m-%d 16:30:00'),
        })

        self.env['event.event.ticket'].create([{
            'name':
            'Standard',
            'event_id':
            self.event_2.id,
            'product_id':
            self.env.ref('event_sale.product_product_event').id,
            'start_sale_date':
            (Datetime.today() -
             timedelta(days=5)).strftime('%Y-%m-%d 07:00:00'),
            'end_sale_date':
            (Datetime.today() + timedelta(90)).strftime('%Y-%m-%d'),
            'price':
            1000.0,
        }, {
            'name':
            'VIP',
            'event_id':
            self.event_2.id,
            'product_id':
            self.env.ref('event_sale.product_product_event').id,
            'end_sale_date':
            (Datetime.today() + timedelta(90)).strftime('%Y-%m-%d'),
            'price':
            1500.0,
        }])

        (self.env.ref('base.partner_admin') + self.partner_demo).write({
            'street':
            '215 Vine St',
            'city':
            'Scranton',
            'zip':
            '18503',
            'country_id':
            self.env.ref('base.us').id,
            'state_id':
            self.env.ref('base.state_us_39').id,
            'phone':
            '+1 555-555-5555',
            'email':
            '*****@*****.**',
        })

        cash_journal = self.env['account.journal'].create({
            'name': 'Cash - Test',
            'type': 'cash',
            'code': 'CASH - Test'
        })
        self.env.ref(
            'payment.payment_acquirer_transfer').journal_id = cash_journal
    def test_course_certification_employee(self):
        user_demo = self.user_demo
        user_demo.flush()
        # Avoid Billing/Shipping address page
        user_demo.write({
            'groups_id': [(5, 0), (4, self.env.ref('base.group_user').id)],
            'street':
            '215 Vine St',
            'city':
            'Scranton',
            'zip':
            '18503',
            'country_id':
            self.env.ref('base.us').id,
            'state_id':
            self.env.ref('base.state_us_39').id,
            'phone':
            '+1 555-555-5555',
            'email':
            '*****@*****.**',
        })

        # Specify Accounting Data
        cash_journal = self.env['account.journal'].create({
            'name': 'Cash - Test',
            'type': 'cash',
            'code': 'CASH - Test'
        })
        self.env['payment.acquirer'].search([('journal_id', '=', False)
                                             ]).journal_id = cash_journal
        a_recv = self.env['account.account'].create({
            'code':
            'X1012',
            'name':
            'Debtors - (test)',
            'reconcile':
            True,
            'user_type_id':
            self.env.ref('account.data_account_type_receivable').id,
        })
        a_pay = self.env['account.account'].create({
            'code':
            'X1111',
            'name':
            'Creditors - (test)',
            'user_type_id':
            self.env.ref('account.data_account_type_payable').id,
            'reconcile':
            True,
        })

        Property = self.env['ir.property']
        Property._set_default('property_account_receivable_id', 'res.partner',
                              a_recv, self.env.company)
        Property._set_default('property_account_payable_id', 'res.partner',
                              a_pay, self.env.company)

        product_course_channel_6 = self.env['product.product'].create({
            'name':
            'DIY Furniture Course',
            'list_price':
            100.0,
            'type':
            'service',
            'is_published':
            True,
        })

        furniture_survey = self.env['survey.survey'].create({
            'title':
            'Furniture Creation Certification',
            'access_token':
            '5632a4d7-48cf-aaaa-8c52-2174d58cf50b',
            'state':
            'open',
            'access_mode':
            'public',
            'users_can_go_back':
            True,
            'users_login_required':
            True,
            'scoring_type':
            'scoring_with_answers',
            'certification':
            True,
            'certification_mail_template_id':
            self.env.ref('survey.mail_template_certification').id,
            'is_attempts_limited':
            True,
            'attempts_limit':
            3,
            'description':
            "<p>Test your furniture knowledge!</p>",
            'question_and_page_ids':
            [(0, 0, {
                'title':
                'Furniture',
                'sequence':
                1,
                'is_page':
                True,
                'description':
                "&lt;p&gt;Test your furniture knowledge!&lt;/p&gt",
            }),
             (0, 0, {
                 'title':
                 'What type of wood is the best for furniture?',
                 'sequence':
                 2,
                 'question_type':
                 'simple_choice',
                 'constr_mandatory':
                 True,
                 'suggested_answer_ids': [(0, 0, {
                     'value': 'Fir',
                     'sequence': 1,
                 }),
                                          (0, 0, {
                                              'value': 'Oak',
                                              'sequence': 2,
                                              'is_correct': True,
                                              'answer_score': 2.0,
                                          }),
                                          (0, 0, {
                                              'value': 'Ash',
                                              'sequence': 3,
                                          }),
                                          (0, 0, {
                                              'value': 'Beech',
                                              'sequence': 4,
                                          })]
             }),
             (0, 0, {
                 'title':
                 'Select all the furniture shown in the video',
                 'sequence':
                 3,
                 'question_type':
                 'multiple_choice',
                 'column_nb':
                 '4',
                 'suggested_answer_ids': [(0, 0, {
                     'value': 'Chair',
                     'sequence': 1,
                     'is_correct': True,
                     'answer_score': 1.0,
                 }),
                                          (0, 0, {
                                              'value': 'Table',
                                              'sequence': 2,
                                              'answer_score': -1.0,
                                          }),
                                          (0, 0, {
                                              'value': 'Desk',
                                              'sequence': 3,
                                              'is_correct': True,
                                              'answer_score': 1.0,
                                          }),
                                          (0, 0, {
                                              'value': 'Shelve',
                                              'sequence': 4,
                                              'is_correct': True,
                                              'answer_score': 1.0,
                                          }),
                                          (0, 0, {
                                              'value': 'Bed',
                                              'sequence': 5,
                                              'answer_score': -1.0,
                                          })]
             }),
             (0, 0, {
                 'title':
                 'What do you think about the content of the course? (not rated)',
                 'sequence': 4,
                 'question_type': 'text_box',
             })]
        })

        slide_channel_demo_6_furn3 = self.env['slide.channel'].create({
            'name':
            'DIY Furniture - TEST',
            'user_id':
            self.env.ref('base.user_admin').id,
            'enroll':
            'payment',
            'product_id':
            product_course_channel_6.id,
            'channel_type':
            'training',
            'allow_comment':
            True,
            'promote_strategy':
            'most_voted',
            'is_published':
            True,
            'description':
            'So much amazing certification.',
            'create_date':
            Datetime.now() - relativedelta(days=2),
            'slide_ids': [(0, 0, {
                'name': 'DIY Furniture Certification',
                'sequence': 1,
                'slide_type': 'certification',
                'category_id': False,
                'is_published': True,
                'is_preview': False,
                'description': "It's time to test your knowledge!",
                'survey_id': furniture_survey.id,
            })]
        })

        self.browser_js(
            '/slides',
            'odoo.__DEBUG__.services["web_tour.tour"].run("certification_member")',
            'odoo.__DEBUG__.services["web_tour.tour"].tours.certification_member.ready',
            login=user_demo.login)
Пример #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)
Пример #49
0
 def _compute_presence_state(self):
     super()._compute_presence_state()
     employees = self.filtered(lambda employee: employee.hr_presence_state
                               != 'present' and not employee.is_absent)
     company = self.env.company
     for employee in employees:
         if not employee.is_absent and company.hr_presence_last_compute_date and company.hr_presence_last_compute_date.day == Datetime.now().day and \
                 (employee.email_sent or employee.ip_connected or employee.manually_set_present):
             employee.hr_presence_state = 'present'
    def test_event_configuration_from_type(self):
        """ Test data computation of event coming from its event.type template.
        Some one2many notably are duplicated from type configuration and some
        advanced testing is required, notably mail schedulers. """
        self.assertEqual(self.env.user.tz, 'Europe/Brussels')

        # ------------------------------------------------------------
        # STARTING DATA
        # ------------------------------------------------------------

        event_type = self.env['event.type'].browse(self.event_type_complex.id)
        event_type.write({
            'use_mail_schedule': False,
            'use_ticket': False,
        })
        self.assertEqual(event_type.event_type_mail_ids,
                         self.env['event.type.mail'])
        self.assertEqual(event_type.event_type_ticket_ids,
                         self.env['event.type.ticket'])

        event = self.env['event.event'].create({
            'name':
            'Event Update Type',
            'date_begin':
            FieldsDatetime.to_string(datetime.today() + timedelta(days=1)),
            'date_end':
            FieldsDatetime.to_string(datetime.today() + timedelta(days=15)),
        })
        self.assertEqual(event.date_tz, self.env.user.tz)
        self.assertFalse(event.seats_limited)
        self.assertFalse(event.auto_confirm)
        self.assertEqual(event.event_mail_ids, self.env['event.mail'])
        self.assertEqual(event.event_ticket_ids,
                         self.env['event.event.ticket'])

        registration = self._create_registrations(event, 1)
        self.assertEqual(registration.state,
                         'draft')  # event is not auto confirm

        # ------------------------------------------------------------
        # FILL SYNC TEST
        # ------------------------------------------------------------

        # change template to a one with mails -> fill event as it is void
        event_type.write({
            'use_mail_schedule':
            True,
            'event_type_mail_ids':
            [(5, 0),
             (0, 0, {
                 'interval_nbr':
                 1,
                 'interval_unit':
                 'days',
                 'interval_type':
                 'before_event',
                 'template_id':
                 self.env['ir.model.data'].xmlid_to_res_id(
                     'event.event_reminder')
             })],
            'use_ticket':
            True,
            'event_type_ticket_ids': [(5, 0),
                                      (0, 0, {
                                          'name': 'TestRegistration'
                                      })],
        })
        event.write({'event_type_id': event_type.id})
        self.assertEqual(event.date_tz, 'Europe/Paris')
        self.assertTrue(event.seats_limited)
        self.assertEqual(event.seats_max, event_type.seats_max)
        self.assertTrue(event.auto_confirm)
        # check 2many fields being populated
        self.assertEqual(len(event.event_mail_ids), 1)
        self.assertEqual(event.event_mail_ids.interval_nbr, 1)
        self.assertEqual(event.event_mail_ids.interval_unit, 'days')
        self.assertEqual(event.event_mail_ids.interval_type, 'before_event')
        self.assertEqual(event.event_mail_ids.template_id,
                         self.env.ref('event.event_reminder'))
        self.assertEqual(len(event.event_ticket_ids), 1)

        # update template, unlink from event -> should not impact event
        event_type.write({'has_seats_limitation': False})
        self.assertEqual(event_type.seats_max, 0)
        self.assertTrue(event.seats_limited)
        self.assertEqual(event.seats_max, 30)  # original template value
        event.write({'event_type_id': False})
        self.assertEqual(event.event_type_id, self.env["event.type"])

        # set template back -> update event
        event.write({'event_type_id': event_type.id})
        self.assertFalse(event.seats_limited)
        self.assertEqual(event.seats_max, 0)
        self.assertEqual(len(event.event_ticket_ids), 1)
        event_ticket1 = event.event_ticket_ids[0]
        self.assertEqual(event_ticket1.name, 'TestRegistration')

        # ------------------------------------------------------------
        # RESET TEST
        # ------------------------------------------------------------

        # link registration to ticket
        registration.write({'event_ticket_id': event_ticket1.id})
        self.assertEqual(registration.event_ticket_id, event_ticket1)

        # change template to a void one for mails -> reset event lines that are void
        # change template to a one with other tickets -> keep line linked to a registration
        event_type.write({
            'use_mail_schedule':
            False,
            'event_type_mail_ids': [(5, 0)],
            'event_type_ticket_ids': [(5, 0), (0, 0, {
                'name': 'Registration1'
            }), (0, 0, {
                'name': 'Registration2'
            })],
        })
        event._compute_event_ticket_ids()
        event._compute_event_mail_ids()
        self.assertEqual(event.event_mail_ids, self.env['event.mail'])
        self.assertEqual(len(event.event_ticket_ids), 3)
        self.assertEqual(
            set(event.mapped('event_ticket_ids.name')),
            set(['TestRegistration', 'Registration1', 'Registration2']))
        # registration loose its ticket
        self.assertEqual(registration.event_ticket_id, event_ticket1)

        # change template to a one with different mails -> reset event
        event_type.write({
            'use_mail_schedule':
            True,
            'event_type_mail_ids':
            [(5, 0),
             (0, 0, {
                 'interval_nbr':
                 3,
                 'interval_unit':
                 'days',
                 'interval_type':
                 'after_event',
                 'template_id':
                 self.env['ir.model.data'].xmlid_to_res_id(
                     'event.event_reminder')
             })]
        })
        event._compute_event_ticket_ids()
        event._compute_event_mail_ids()
        self.assertEqual(len(event.event_mail_ids), 1)
        self.assertEqual(event.event_mail_ids.interval_nbr, 3)
        self.assertEqual(event.event_mail_ids.interval_type, 'after_event')
Пример #51
0
    def test_calendar_leave_intervals_timezone(self):
        # _iter_leave_intervals takes UTC and outputs UTC
        # Leave is taken by user in US/Alaska timezone
        # It should be visible at the right time for every timezone
        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)

        # Checking for 'Europe/Brussels'
        self.env.user.tz = 'Europe/Brussels'
        leaves = list(
            self.calendar._iter_leave_intervals(
                to_naive_utc(Datetime.from_string('2013-02-26 14:00:00'),
                             self.env.user),
                to_naive_utc(Datetime.from_string('2013-02-26 15:30:00'),
                             self.env.user), self.resource1_id))
        self.assertEqual(len(leaves), 0)

        leaves = list(
            self.calendar._iter_leave_intervals(
                to_naive_utc(Datetime.from_string('2013-02-26 08:00:00'),
                             self.env.user),
                to_naive_utc(Datetime.from_string('2013-02-26 11:00:00'),
                             self.env.user), self.resource1_id))[0]
        self.assertEqual(len(leaves), 1)
        self.assertEqual(to_tuple(leaves[0]),
                         (Datetime.from_string('2013-02-26 07:00:00'),
                          Datetime.from_string('2013-02-26 10:00:00')))

        leaves = list(
            self.calendar._iter_leave_intervals(
                to_naive_utc(Datetime.from_string('2013-02-22 08:00:00'),
                             self.env.user),
                to_naive_utc(Datetime.from_string('2013-02-22 20:00:00'),
                             self.env.user), self.resource1_id))[0]
        self.assertEqual(len(leaves), 2)
        self.assertEqual(to_tuple(leaves[0]),
                         (Datetime.from_string('2013-02-22 07:00:00'),
                          Datetime.from_string('2013-02-22 12:00:00')))

        # Checking for 'Japan'
        self.env.user.tz = 'Japan'
        leaves = list(
            self.calendar._iter_leave_intervals(
                to_naive_utc(Datetime.from_string('2013-02-26 14:00:00'),
                             self.env.user),
                to_naive_utc(Datetime.from_string('2013-02-26 15:30:00'),
                             self.env.user), self.resource1_id))
        self.assertEqual(len(leaves), 0)

        leaves = list(
            self.calendar._iter_leave_intervals(
                to_naive_utc(Datetime.from_string('2013-02-26 08:00:00'),
                             self.env.user),
                to_naive_utc(Datetime.from_string('2013-02-26 11:00:00'),
                             self.env.user), self.resource1_id))[0]
        self.assertEqual(len(leaves), 1)
        self.assertEqual(to_tuple(leaves[0]),
                         (Datetime.from_string('2013-02-25 23:00:00'),
                          Datetime.from_string('2013-02-26 02:00:00')))

        leaves = list(
            self.calendar._iter_leave_intervals(
                to_naive_utc(Datetime.from_string('2013-02-22 08:00:00'),
                             self.env.user),
                to_naive_utc(Datetime.from_string('2013-02-22 20:00:00'),
                             self.env.user), self.resource1_id))[0]
        self.assertEqual(len(leaves), 2)
        self.assertEqual(to_tuple(leaves[0]),
                         (Datetime.from_string('2013-02-21 23:00:00'),
                          Datetime.from_string('2013-02-22 04:00:00')))
Пример #52
0
    def _execute_email(self, traces):
        res_ids = [r for r in set(traces.mapped('res_id'))]

        mailing = self.mass_mailing_id.with_context(
            default_marketing_activity_id=self.ids[0],
            active_ids=res_ids,
        )

        # we only allow to continue if the user has sufficient rights, as a sudo() follows
        if not self.env.is_superuser() and not self.user_has_groups(
                'marketing_automation.group_marketing_automation_user'):
            raise AccessError(
                _('To use this feature you should be an administrator or belong to the marketing automation group.'
                  ))
        try:
            mailing.sudo().action_send_mail(res_ids)
        except Exception as e:
            _logger.warning(
                'Marketing Automation: activity <%s> encountered mass mailing issue %s',
                self.id,
                str(e),
                exc_info=True)
            traces.write({
                'state':
                'error',
                'schedule_date':
                Datetime.now(),
                'state_msg':
                _('Exception in mass mailing: %s', str)(e),
            })
        else:
            failed_stats = self.env['mailing.trace'].sudo().search([
                ('marketing_trace_id', 'in', traces.ids), '|',
                ('exception', '!=', False), ('ignored', '!=', False)
            ])
            ignored_doc_ids = [
                stat.res_id for stat in failed_stats if stat.exception
            ]
            error_doc_ids = [
                stat.res_id for stat in failed_stats if stat.ignored
            ]

            processed_traces = traces
            ignored_traces = traces.filtered(
                lambda trace: trace.res_id in ignored_doc_ids)
            error_traces = traces.filtered(
                lambda trace: trace.res_id in error_doc_ids)

            if ignored_traces:
                ignored_traces.write({
                    'state': 'canceled',
                    'schedule_date': Datetime.now(),
                    'state_msg': _('Email ignored')
                })
                processed_traces = processed_traces - ignored_traces
            if error_traces:
                error_traces.write({
                    'state': 'error',
                    'schedule_date': Datetime.now(),
                    'state_msg': _('Email failed')
                })
                processed_traces = processed_traces - error_traces
            if processed_traces:
                processed_traces.write({
                    'state': 'processed',
                    'schedule_date': Datetime.now(),
                })
        return True
Пример #53
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'))
     ]
Пример #54
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')
        })
Пример #55
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'].sudo(self.user_market)
        Activity = self.env['marketing.activity'].sudo(self.user_market)
        MassMail = self.env['mail.mass_mailing'].sudo(self.user_market)
        ServerAction = self.env['ir.actions.server'].sudo(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',
            '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',
            'domain':
            '%s' % ([('name', 'ilike', 'Test')]),
            'campaign_id':
            campaign.id,
            'parent_id':
            act_0.id,
            'activity_type':
            'action',
            'server_action_id':
            server_action.sudo(self.user_market).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
        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])
Пример #56
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')
Пример #57
0
    def _check_presence(self):
        company = self.env.company
        if not company.hr_presence_last_compute_date or \
                company.hr_presence_last_compute_date.day != Datetime.now().day:
            self.env['hr.employee'].search([('company_id', '=', company.id)
                                            ]).write({
                                                'email_sent':
                                                False,
                                                'ip_connected':
                                                False,
                                                'manually_set_present':
                                                False
                                            })

        employees = self.env['hr.employee'].search([('company_id', '=',
                                                     company.id)])
        all_employees = employees

        # Check on IP
        if self.env['ir.config_parameter'].sudo().get_param(
                'hr_presence.hr_presence_control_ip'):
            ip_list = company.hr_presence_control_ip_list
            ip_list = ip_list.split(',') if ip_list else []
            ip_employees = self.env['hr.employee']
            for employee in employees:
                employee_ips = self.env['res.users.log'].search([
                    ('create_uid', '=', employee.user_id.id),
                    ('ip', '!=', False),
                    ('create_date', '>=',
                     Datetime.to_string(Datetime.now().replace(hour=0,
                                                               minute=0,
                                                               second=0,
                                                               microsecond=0)))
                ]).mapped('ip')
                if any([ip in ip_list for ip in employee_ips]):
                    ip_employees |= employee
            ip_employees.write({'ip_connected': True})
            employees = employees - ip_employees

        # Check on sent emails
        if self.env['ir.config_parameter'].sudo().get_param(
                'hr_presence.hr_presence_control_email'):
            email_employees = self.env['hr.employee']
            threshold = company.hr_presence_control_email_amount
            for employee in employees:
                sent_emails = self.env['mail.message'].search_count([
                    ('author_id', '=', employee.user_id.partner_id.id),
                    ('date', '>=',
                     Datetime.to_string(Datetime.now().replace(
                         hour=0, minute=0, second=0, microsecond=0))),
                    ('date', '<=', Datetime.to_string(Datetime.now()))
                ])
                if sent_emails >= threshold:
                    email_employees |= employee
            email_employees.write({'email_sent': True})
            employees = employees - email_employees

        company.sudo().hr_presence_last_compute_date = Datetime.now()

        for employee in all_employees:
            employee.hr_presence_state_display = employee.hr_presence_state
Пример #58
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'))
Пример #59
0
    def _test_leave(self):
        # --------------------------------------------------
        # Holiday manager: creates leave types
        # --------------------------------------------------
        self.leave_type_1 = self.create_leave_type(
            user=self.hr_holidays_manager,
            name='Leave Type (no allocation, validation HR, day)',
            allocation='no',
            request_unit='day',
            validation='hr',
        )
        self.leave_type_2 = self.create_leave_type(
            user=self.hr_holidays_manager,
            name='Leave Type (allocation by HR, no validation, half day)',
            allocation='fixed',
            request_unit='half_day',
            validation='no_validation',
        )
        self.leave_type_3 = self.create_leave_type(
            user=self.hr_holidays_manager,
            name='Leave Type (allocation request, validation both, hour)',
            allocation='fixed_allocation',
            request_unit='hour',
            validation='both',
        )

        # --------------------------------------------------
        # Holiday user: Allocation
        # --------------------------------------------------
        allocation_no_validation = self.create_allocation(
            user=self.hr_holidays_user,
            employee=self.user.employee_id,
            leave_type=self.leave_type_2,
        )

        # Holiday user refuse allocation
        allocation_no_validation.action_refuse()
        self.assertEqual(allocation_no_validation.state, 'refuse')

        # Holiday manager reset to draft
        allocation_no_validation.with_user(self.hr_holidays_manager).action_draft()
        self.assertEqual(allocation_no_validation.state, 'draft')

        # Holiday user approve allocation
        allocation_no_validation.with_user(self.user).action_confirm()
        allocation_no_validation.action_approve()
        self.assertEqual(allocation_no_validation.state, 'validate')
        self.assertEqual(allocation_no_validation.first_approver_id, self.hr_holidays_user.employee_id)

        # --------------------------------------------------
        # User: Allocation request
        # --------------------------------------------------

        # User request an allocation
        allocation = self.create_allocation(
            user=self.user,
            employee=self.user.employee_id,
            leave_type=self.leave_type_3,
        )
        self.assertEqual(allocation.state, 'confirm')

        # Holyday User approves
        allocation.with_user(self.hr_holidays_user).action_approve()
        self.assertEqual(allocation.state, 'validate1')
        self.assertEqual(allocation.first_approver_id, self.hr_holidays_user.employee_id)

        # Holiday Manager validates
        allocation.with_user(self.hr_holidays_manager).action_validate()
        self.assertEqual(allocation.state, 'validate')
        self.assertEqual(allocation.second_approver_id, self.hr_holidays_manager.employee_id)

        # --------------------------------------------------
        # User: Leave request
        # --------------------------------------------------

        # User request a leave which does not require validation
        leave_form = Form(self.env['hr.leave'].with_user(self.user))
        leave_form.holiday_status_id = allocation_no_validation.holiday_status_id
        leave_form.request_unit_half = True
        leave_form.request_date_from = Date.today() + relativedelta(days=1)
        leave_form.request_date_from_period = 'am'
        self.assertEqual(leave_form.number_of_days, 0.5, "Onchange should have computed 0.5 days")
        leave = leave_form.save()
        self.assertEqual(leave.state, 'validate', "Should be automatically validated")

        # User request a leave that doesn't require allocation
        leave = self.create_leave(
            user=self.user,
            leave_type=self.leave_type_1,
            start=Datetime.now() + relativedelta(days=2),
            end=Datetime.now() + relativedelta(days=3)
        )

        # User request a leave that require validation
        leave = self.create_leave(
            user=self.user,
            leave_type=allocation.holiday_status_id,
            start=Datetime.now() + relativedelta(days=6),
            end=Datetime.now() + relativedelta(days=8)
        )
        self.assertEqual(leave.state, 'confirm', "Should be in `confirm` state")

        # Team leader approves
        leave.with_user(self.user_leave_team_leader).action_approve()
        self.assertEqual(leave.state, 'validate1')
        self.assertEqual(leave.first_approver_id, self.user_leave_team_leader.employee_id)

        # Holiday manager applies second approval
        leave.with_user(self.hr_holidays_manager).action_validate()

        self.assertEqual(leave.state, 'validate')
        self.assertEqual(leave.second_approver_id, self.hr_holidays_manager.employee_id)
Пример #60
0
 def _compute_atn(self):
     now = Datetime.now()
     for model in self:
         model.default_atn = self.env['fleet.vehicle']._get_car_atn(
             now, model.default_car_value, model.default_fuel_type,
             model.default_co2)