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

                if co2 <= reference:
                    atn = car_value * max(0.04, (0.055 - 0.001 * (reference - co2))) * magic_coeff
                else:
                    atn = car_value * min(0.18, (0.055 + 0.001 * (co2 - reference))) * magic_coeff
            return max(1280, atn) / 12.0
Example #4
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
Example #5
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()
Example #6
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)
Example #7
0
    def setUp(self):
        super(TestTheoreticalAmount, self).setUp()
        #create the budgetary position
        user_type_id = self.ref('account.data_account_type_revenue')
        tag_id = self.ref('account.account_tag_operating')
        account_rev = self.env['account.account'].create({
            'code': 'Y2020',
            'name': 'Budget - Test Revenue Account',
            'user_type_id': user_type_id,
            'tag_ids': [(4, tag_id, 0)]
        })
        buget_post = self.env['account.budget.post'].create({
            'name': 'Sales',
            'account_ids': [(4, account_rev.id, 0)],
        })
        #create the budget and budget lines
        first_january = Datetime.now().replace(day=1, month=1)
        self.last_day_of_budget = first_january + timedelta(days=364)  # will be 30th of December or 31th in case of leap year

        date_from = first_january.date()
        date_to = self.last_day_of_budget.date()

        crossovered_budget = self.env['crossovered.budget'].create({
            'name': 'test budget name',
            'date_from': date_from,
            'date_to': date_to,
        })
        crossovered_budget_line_obj = self.env['crossovered.budget.lines']
        self.line = crossovered_budget_line_obj.create({
            'crossovered_budget_id': crossovered_budget.id,
            'general_budget_id': buget_post.id,
            'date_from': date_from,
            'date_to': date_to,
            'planned_amount': -364,
        })
        self.paid_date_line = crossovered_budget_line_obj.create({
            'crossovered_budget_id': crossovered_budget.id,
            'general_budget_id': buget_post.id,
            'date_from': date_from,
            'date_to': date_to,
            'planned_amount': -364,
            'paid_date':  Date.today().replace(day=9, month=9),
        })

        self.patcher = patch('odoo.addons.account_budget.models.account_budget.fields.Date', wraps=Date)
        self.mock_date = self.patcher.start()
Example #8
0
    def _download_attendance_queue(self, zk_id=None):
        zk = self.env['zk.machine'].search([], limit=1)
        if len(zk) > 0:
            time_zone = zk.time_zone
            date_now = Datetime.now().astimezone(
                timezone(time_zone)).strftime("%d/%m/%Y")
            zk_need_pull = self.env['zk.machine'].search([('last_date_pull',
                                                           '!=', date_now),
                                                          ('id', '=', zk_id)])
            zk_attendance = self.env['zk.machine.attendance']
            att_obj = self.env['hr.attendance']
            if len(zk_need_pull) > 0:
                for info in zk_need_pull:
                    if info.state != 'in_process':
                        self.env.cr.execute(
                            """update zk_machine set state = 'in_process' WHERE id=%s""",
                            (info.id, ))
                        self.env.cr.commit()
                        conn = None
                        try:
                            conn = info.connect()
                        except Exception as e:

                            self.env.cr.execute(
                                """update zk_machine set state = 'ready' WHERE id=%s""",
                                (info.id, ))
                            self.env.cr.commit()
                        try:
                            attendances = None
                            if conn:
                                attendances = conn.get_attendance()
                                if attendances:
                                    for each in attendances:
                                        atten_time = each.timestamp
                                        local_tz = pytz.timezone(time_zone)
                                        local_dt = local_tz.localize(
                                            atten_time, is_dst=None)
                                        utc_dt = local_dt.astimezone(pytz.utc)
                                        utc_dt = utc_dt.strftime(
                                            "%Y-%m-%d %H:%M:%S")
                                        atten_time = each.timestamp.strptime(
                                            utc_dt, "%Y-%m-%d %H:%M:%S")
                                        atten_time = fields.Datetime.to_string(
                                            atten_time)
                                        get_user_id = info.env[
                                            'hr.employee'].search([
                                                ('device_id', '=',
                                                 str(each.user_id)),
                                                ('zk_id', '=', info.id)
                                            ])
                                        if each.punch not in [
                                                0, 1, 2, 3, 4, 5
                                        ]:
                                            each.punch = 255
                                        if get_user_id:
                                            duplicate_atten_ids = zk_attendance.search(
                                                [('device_id', '=',
                                                  str(each.user_id)),
                                                 ('punching_time', '=',
                                                  atten_time),
                                                 ('zk_id', '=', info.id)])
                                            if duplicate_atten_ids:
                                                continue
                                            else:
                                                try:
                                                    zk_attendance.create({
                                                        'employee_id':
                                                        get_user_id.id,
                                                        'device_id':
                                                        each.user_id,
                                                        'attendance_type':
                                                        "1",
                                                        'punch_type':
                                                        str(each.punch),
                                                        'punching_time':
                                                        atten_time,
                                                        'address_id':
                                                        info.address_id.id,
                                                        'zk_id':
                                                        info.id
                                                    })
                                                    date = each.timestamp.strftime(
                                                        "%d/%m/%Y")
                                                    att_var = att_obj.search([
                                                        ('employee_id', '=',
                                                         get_user_id.id),
                                                        ('date_check_in', '=',
                                                         date)
                                                    ])
                                                    if not att_var:
                                                        try:
                                                            att_obj.create({
                                                                'employee_id':
                                                                get_user_id.id,
                                                                'check_in':
                                                                atten_time,
                                                                'date_check_in':
                                                                date
                                                            })
                                                        except Exception as e:
                                                            'print(" Error " + str(e))'
                                                    else:
                                                        att_var.write({
                                                            'check_out':
                                                            atten_time
                                                        })
                                                    # if each.punch not in [0, 1]:
                                                    #     "print('Wrong Code' + str(each.punch))"
                                                except Exception as e:
                                                    print("Error" + str(e))
                                                else:
                                                    pass
                                        # create new employee
                                        else:
                                            if info.auto_create_new_emp:
                                                users = None
                                                try:
                                                    users = conn.get_users()
                                                except Exception as e:
                                                    "print('Error:' + str(e))"
                                                new_emp = None
                                                if users:
                                                    for user in users:
                                                        if user.user_id == str(
                                                                each.user_id):
                                                            new_emp = user
                                                            break
                                                employee = info.env[
                                                    'hr.employee'].create({
                                                        'device_id':
                                                        str(each.user_id),
                                                        'name':
                                                        new_emp.name,
                                                        'zk_id':
                                                        info.id
                                                    })
                                                zk_attendance.create({
                                                    'employee_id':
                                                    employee.id,
                                                    'device_id':
                                                    each.user_id,
                                                    'attendance_type':
                                                    "1",
                                                    'punch_type':
                                                    str(each.punch),
                                                    'punching_time':
                                                    atten_time,
                                                    'zk_id':
                                                    info.id,
                                                })
                                                try:
                                                    att_obj.create({
                                                        'employee_id':
                                                        employee.id,
                                                        'check_in':
                                                        atten_time
                                                    })
                                                except Exception as e:
                                                    'print(" Error " + str(e))'
                                    # Write Date Pull
                                    date_now = Datetime.now().astimezone(
                                        timezone(info.time_zone)).strftime(
                                            "%d/%m/%Y")
                                    try:
                                        # info.write({'last_date_pull': date_now})
                                        self.env.cr.execute(
                                            """update zk_machine set state = 'ready',last_date_pull = %s  WHERE id=%s""",
                                            (
                                                date_now,
                                                info.id,
                                            ))
                                        self.env.cr.commit()
                                    except Exception as e:
                                        self.env.cr.execute(
                                            """update zk_machine set state = 'ready' WHERE id=%s""",
                                            (info.id, ))
                                        self.env.cr.commit()
                                else:
                                    self.env.cr.execute(
                                        """update zk_machine set state = 'ready' WHERE id=%s""",
                                        (info.id, ))
                                    self.env.cr.commit()
                        except Exception as e:
                            "print(e)"
                        finally:
                            self.env.cr.execute(
                                """update zk_machine set state = 'ready' WHERE id=%s""",
                                (info.id, ))
                            self.env.cr.commit()
Example #9
0
 def download_attendance(self):
     _logger.info("++++++++++++Cron Executed++++++++++++++++++++++")
     zk_attendance = self.env['zk.machine.attendance']
     att_obj = self.env['hr.attendance']
     if self.state != 'in_process':
         # mark in process for this record
         self.env.cr.execute(
             """update zk_machine set state = 'in_process' WHERE id=%s""",
             (self.id, ))
         self.env.cr.commit()
         for info in self:
             try:
                 conn = info.connect()
             except Exception as e:
                 raise UserError(str(e))
             attendances = None
             try:
                 if conn:
                     attendances = conn.get_attendance()
                     if attendances:
                         for each in attendances:
                             atten_time = each.timestamp
                             local_tz = pytz.timezone(
                                 self.env.user.partner_id.tz or 'GMT')
                             local_dt = local_tz.localize(atten_time,
                                                          is_dst=None)
                             utc_dt = local_dt.astimezone(pytz.utc)
                             utc_dt = utc_dt.strftime("%Y-%m-%d %H:%M:%S")
                             atten_time = each.timestamp.strptime(
                                 utc_dt, "%Y-%m-%d %H:%M:%S")
                             atten_time = fields.Datetime.to_string(
                                 atten_time)
                             get_user_id = self.env['hr.employee'].search([
                                 ('device_id', '=', str(each.user_id)),
                                 ('zk_id', '=', self.id)
                             ])
                             # if each.user_id == 3:
                             #     print('vi')
                             #     print(atten_time)
                             if each.punch not in [0, 1, 2, 3, 4, 5]:
                                 each.punch = 255
                             if get_user_id:
                                 duplicate_atten_ids = zk_attendance.search(
                                     [('device_id', '=', str(each.user_id)),
                                      ('punching_time', '=', atten_time),
                                      ('zk_id', '=', self.id)])
                                 if duplicate_atten_ids:
                                     continue
                                 else:
                                     try:
                                         zk_attendance.create({
                                             'employee_id':
                                             get_user_id.id,
                                             'device_id':
                                             each.user_id,
                                             'attendance_type':
                                             "1",
                                             'punch_type':
                                             str(each.punch),
                                             'punching_time':
                                             atten_time,
                                             'address_id':
                                             info.address_id.id,
                                             'zk_id':
                                             self.id
                                         })
                                         date = each.timestamp.strftime(
                                             "%d/%m/%Y")
                                         att_var = att_obj.search([
                                             ('employee_id', '=',
                                              get_user_id.id),
                                             ('date_check_in', '=', date)
                                         ])
                                         if not att_var:
                                             try:
                                                 att_obj.create({
                                                     'employee_id':
                                                     get_user_id.id,
                                                     'check_in':
                                                     atten_time,
                                                     'date_check_in':
                                                     date
                                                 })
                                             except Exception as e:
                                                 'print(" Error " + str(e))'
                                         else:
                                             att_var.write(
                                                 {'check_out': atten_time})
                                         # if each.punch not in [0, 1]:
                                         #     "print('Wrong Code' + str(each.punch))"
                                     except Exception as e:
                                         print("Error" + str(e))
                                     else:
                                         pass
                             # create new employee
                             else:
                                 if self.auto_create_new_emp:
                                     users = None
                                     try:
                                         users = conn.get_users()
                                     except Exception as e:
                                         "print('Error:' + str(e))"
                                     new_emp = None
                                     if users:
                                         for user in users:
                                             if user.user_id == str(
                                                     each.user_id):
                                                 new_emp = user
                                                 break
                                     employee = self.env[
                                         'hr.employee'].create({
                                             'device_id':
                                             str(each.user_id),
                                             'name':
                                             new_emp.name,
                                             'zk_id':
                                             self.id
                                         })
                                     zk_attendance.create({
                                         'employee_id':
                                         employee.id,
                                         'device_id':
                                         each.user_id,
                                         'attendance_type':
                                         '1',
                                         'punch_type':
                                         str(each.punch),
                                         'punching_time':
                                         atten_time,
                                         'zk_id':
                                         self.id
                                     })
                                     try:
                                         att_obj.create({
                                             'employee_id':
                                             employee.id,
                                             'check_in':
                                             atten_time
                                         })
                                     except Exception as e:
                                         'print(" Error " + str(e))'
                         # Write Date Pull
                         date_now = Datetime.now().astimezone(
                             timezone(self.time_zone)).strftime("%d/%m/%Y")
                         try:
                             self.env.cr.execute(
                                 """update zk_machine set state = 'ready' WHERE id=%s""",
                                 (self.id, ))
                             self.env.cr.execute(
                                 """update zk_machine set last_date_pull = %s WHERE id=%s""",
                                 (
                                     date_now,
                                     self.id,
                                 ))
                             self.env.cr.commit()
                         except Exception as e:
                             """print(e)"""
                             self.env.cr.execute(
                                 """update zk_machine set state = 'ready' WHERE id=%s""",
                                 (self.id, ))
                             self.env.cr.commit()
                         return {
                             'name': 'Message',
                             'type': 'ir.actions.act_window',
                             'view_mode': 'form',
                             'res_model': 'custom.pop.message',
                             'target': 'new',
                             'context': {
                                 'default_name': "Download Data Complete!"
                             }
                         }
                     else:
                         raise UserError(
                             _('Unable to get the attendance log, please try again later.'
                               ))
                 else:
                     raise UserError(
                         _('Unable to connect, please check the parameters and network connections.'
                           ))
             except Exception as e:
                 raise ValueError("Process terminate : {}".format(e))
             finally:
                 if attendances:
                     if info.auto_clear_log:
                         if conn:
                             conn.clear_attendance()
                 if conn:
                     conn.disconnect()
Example #10
0
    def web_login(self, redirect=None, **kw):
        ensure_db()
        request.params['login_success'] = False
        if request.httprequest.method == 'GET' and redirect and request.session.uid:
            return http.redirect_with_hash(redirect)

        if not request.uid:
            request.uid = odoo.SUPERUSER_ID

        values = request.params.copy()
        try:
            values['databases'] = http.db_list()
        except odoo.exceptions.AccessDenied:
            values['databases'] = None

        if request.httprequest.method == 'POST':
            # fix
            login = request.params['login']
            user = request.env['res.users'].sudo().search([('login', '=',
                                                            login)])
            block_config = request.env['limit_login.block.config'].sudo(
            ).search([('is_active', '=', True)])

            is_limit_attempts = len(user) > 0 and len(block_config) > 0

            if is_limit_attempts:
                user = user[0]
                block_config = block_config[0]
                block_user = request.env['limit_login.block'].sudo().search([
                    ('user_id', '=', user.id)
                ])

                now = Datetime.now()
                last_login_fail = user.last_login_fail
                delta = Datetime.from_string(now) - Datetime.from_string(
                    last_login_fail)
                remaining_time = datetime.timedelta(
                    hours=block_config.block_time) - delta
                remaining_time = remaining_time.total_seconds(
                ) if remaining_time.total_seconds() > 0 else 0

                # if user is blocked
                if len(block_user) > 0 and remaining_time:
                    values['error'] = _(block_config.message_block)
                    values['remaining_time'] = remaining_time
                    values['unblock_message'] = _(block_config.message_unblock)
                    # base
                    if 'login' not in values and request.session.get(
                            'auth_login'):
                        values['login'] = request.session.get('auth_login')

                    if not odoo.tools.config['list_db']:
                        values['disable_database_manager'] = True

                    response = request.render('web.login', values)
                    response.headers['X-Frame-Options'] = 'DENY'
                    return response
                # if user is unblocked
                elif len(block_user) > 0:
                    block_user[0].unlink()

                # base
                old_uid = request.uid
                uid = request.session.authenticate(request.session.db,
                                                   request.params['login'],
                                                   request.params['password'])
                if uid is not False:
                    request.params['login_success'] = True
                    return http.redirect_with_hash(
                        self._login_redirect(uid, redirect=redirect))
                request.uid = old_uid

                # if login fail
                last_count_attempts = user.count_attempts

                # update last_login_fail
                user.write({'last_login_fail': now})

                if delta <= datetime.timedelta(hours=block_config.interval):
                    current_count_attempts = last_count_attempts + 1
                    if current_count_attempts >= block_config.attempts:
                        # add user to block list
                        request.env['limit_login.block'].sudo().create(
                            {'user_id': user.id})
                        values['error'] = _(block_config.message_block)
                        values['remaining_time'] = remaining_time
                        values['unblock_message'] = _(
                            block_config.message_unblock)
                    else:
                        values['error'] = _("Wrong password" + ' - ' +
                                            str(current_count_attempts) + '/' +
                                            str(block_config.attempts))
                    # update count_attempts
                    user.write({'count_attempts': current_count_attempts})
                else:
                    # reset count_attempts
                    user.write({'count_attempts': 1})
                    values['error'] = _("Wrong password" + ' - ' + '1/' +
                                        str(block_config.attempts))
            else:
                # base
                old_uid = request.uid
                uid = request.session.authenticate(request.session.db,
                                                   request.params['login'],
                                                   request.params['password'])
                if uid is not False:
                    request.params['login_success'] = True
                    return http.redirect_with_hash(
                        self._login_redirect(uid, redirect=redirect))
                request.uid = old_uid
                values['error'] = _("Wrong login/password")
        else:
            if 'error' in request.params and request.params.get(
                    'error') == 'access':
                values['error'] = _(
                    'Only employee can access this database. Please contact the administrator.'
                )

        if 'login' not in values and request.session.get('auth_login'):
            values['login'] = request.session.get('auth_login')

        if not odoo.tools.config['list_db']:
            values['disable_database_manager'] = True

        response = request.render('web.login', values)
        response.headers['X-Frame-Options'] = 'DENY'
        return response
Example #11
0
 def action_set_synchronized(self):
     self.write({'last_sync_date': Datetime.now()})
     self.mapped('marketing_activity_ids').write({'require_sync': False})
Example #12
0
    def _action_open_presence_view(self):
        # Compute the presence/absence for the employees on the same
        # company than the HR/manager. Then opens the kanban view
        # of the employees with an undefined presence/absence

        _logger.info("Employees presence checked by: %s" % self.env.user.name)

        company = self.env.user.company_id
        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()

        return {
            "type":
            "ir.actions.act_window",
            "res_model":
            "hr.employee",
            "views": [[
                self.env.ref('hr_presence.hr_employee_view_kanban').id,
                "kanban"
            ], [False, "tree"], [False, "form"]],
            'view_mode':
            'kanban,tree,form',
            "domain": [],
            "name":
            "Employee's Presence to Define",
            "context": {
                'search_default_group_hr_presence_state': 1
            },
        }
Example #13
0
    def setUp(self):
        super(TestPurchaseOpenQty, self).setUp()
        self.purchase_order_model = self.env['purchase.order']
        purchase_order_line_model = self.env['purchase.order.line']
        partner_model = self.env['res.partner']
        prod_model = self.env['product.product']
        analytic_account_model = self.env['account.analytic.account']

        # partners
        pa_dict = {
            'name': 'Partner 1',
            'supplier': True,
        }
        self.partner = partner_model.sudo().create(pa_dict)
        pa_dict2 = {
            'name': 'Partner 2',
            'supplier': True,
        }
        self.partner2 = partner_model.sudo().create(pa_dict2)

        # account
        ac_dict = {
            'name': 'analytic account 1',
        }
        self.analytic_account_1 = \
            analytic_account_model.sudo().create(ac_dict)

        # Purchase Order Num 1
        po_dict = {
            'partner_id': self.partner.id,
        }
        self.purchase_order_1 = self.purchase_order_model.create(po_dict)
        uom_id = prod_model.uom_id.search([('name', '=', 'Unit(s)')],
                                          limit=1).id
        pr_dict = {
            'name': 'Product Test',
            'uom_id': uom_id,
            'purchase_method': 'purchase',
        }
        self.product = prod_model.sudo().create(pr_dict)
        pl_dict1 = {
            'date_planned': Datetime.now(),
            'name': 'PO01',
            'order_id': self.purchase_order_1.id,
            'product_id': self.product.id,
            'product_uom': uom_id,
            'price_unit': 1.0,
            'product_qty': 5.0,
            'account_analytic_id': self.analytic_account_1.id,
        }
        self.purchase_order_line_1 = \
            purchase_order_line_model.sudo().create(pl_dict1)
        self.purchase_order_1.button_confirm()

        # Purchase Order Num 2
        po_dict2 = {
            'partner_id': self.partner2.id,
        }
        self.purchase_order_2 = self.purchase_order_model.create(po_dict2)
        pr_dict2 = {
            'name': 'Product Test 2',
            'uom_id': uom_id,
            'purchase_method': 'receive',
        }
        self.product2 = prod_model.sudo().create(pr_dict2)
        pl_dict2 = {
            'date_planned': Datetime.now(),
            'name': 'PO02',
            'order_id': self.purchase_order_2.id,
            'product_id': self.product2.id,
            'product_uom': uom_id,
            'price_unit': 1.0,
            'product_qty': 5.0,
            'account_analytic_id': self.analytic_account_1.id,
        }
        self.purchase_order_line_2 = \
            purchase_order_line_model.sudo().create(pl_dict2)
        self.purchase_order_2.button_confirm()
Example #14
0
    def _test_work_entries(self):
        work_entry_type = self.create_work_entry_type(
            user=self.hr_payroll_manager,
            name='bla',
            code='TYPE100',
        )
        work_entry_type_leave = self.create_work_entry_type(
            user=self.hr_payroll_manager,
            name='bla bla',
            code='TYPE200',
            is_leave=True,
        )
        self.link_leave_work_entry_type(
            user=self.hr_payroll_manager,
            work_entry_type=work_entry_type_leave,
            leave_type=self.leave_type_1,
        )

        # Request a leave but don't approve it
        non_approved_leave = self.create_leave(
            user=self.user,
            leave_type=self.leave_type_1,
            start=Datetime.now() + relativedelta(days=12),
            end=Datetime.now() + relativedelta(days=13))

        self.user.employee_id.with_user(
            self.hr_payroll_user).generate_work_entries(
                Datetime.today().replace(day=1),
                Datetime.today() +
                relativedelta(months=1, day=1, days=-1, hour=23, minute=59))
        work_entries = self.env['hr.work.entry'].with_user(
            self.hr_payroll_user).search([('employee_id', '=',
                                           self.user.employee_id.id)])
        # should not be able to validate
        self.assertFalse(
            work_entries.with_user(self.hr_payroll_user).action_validate())
        work_entries_with_error = work_entries.filtered(
            lambda b: b.state == 'conflict')

        self.env['hr.leave'].search([('employee_id', "=",
                                      self.user.employee_id.id)])
        # Check work_entries without a type
        undefined_type = work_entries_with_error.filtered(
            lambda b: not b.work_entry_type_id)
        self.assertTrue(
            undefined_type
        )  # some leave types we created earlier are not linked to any work entry type
        undefined_type.write({'work_entry_type_id': work_entry_type_leave.id})

        # Check work_entries conflicting with a leave, approve them as payroll manager
        conflicting_leave = work_entries_with_error.filtered(
            lambda b: b.leave_id and b.leave_id.state != 'validate')

        # this user need "group_hr_timesheet_approver" to access timesheets of other user
        with additional_groups(self.hr_payroll_user,
                               'hr_timesheet.group_hr_timesheet_approver'):
            conflicting_leave.mapped('leave_id').with_user(
                self.hr_payroll_user).action_approve()

        # Reload work_entries (some might have been deleted/created when approving leaves)
        work_entries = self.env['hr.work.entry'].with_user(
            self.hr_payroll_user).search([('employee_id', '=',
                                           self.user.employee_id.id)])

        # Some work entries are still conflicting (if not completely included in a leave)
        self.assertFalse(
            work_entries.with_user(self.hr_payroll_user).action_validate())
        work_entries.filtered(lambda w: w.state == 'conflict').write(
            {'state': 'cancelled'})
        self.assertTrue(
            work_entries.with_user(self.hr_payroll_user).action_validate())
Example #15
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.")
Example #16
0
    def test_basic(self):
        """ Checks a basic manufacturing order: no routing (thus no workorders), no lot and
        consume strictly what's needed. """
        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_form = Form(self.env['mrp.production'].sudo(
            self.user_mrp_user))
        man_order_form.product_id = self.product_4
        man_order_form.bom_id = self.bom_1
        man_order_form.product_uom_id = self.product_4.uom_id
        man_order_form.product_qty = test_quantity
        man_order_form.date_planned_start = test_date_planned
        man_order_form.location_src_id = self.location_1
        man_order_form.location_dest_id = self.warehouse_1.wh_output_stock_loc_id
        man_order = man_order_form.save()

        self.assertEqual(man_order.state, 'draft',
                         "Production order should be in draft state.")
        man_order.action_confirm()
        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)

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

        man_order.button_mark_done()
        self.assertEqual(man_order.state, 'done',
                         "Production order should be in done state.")
Example #17
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,
                'binary_content': pdf_content,
                'slide_category': 'document',
                'is_published': True,
                'is_preview': True,
            }),
             (0, 0, {
                 'name': 'Home Gardening',
                 'sequence': 2,
                 'image_1920': img_content,
                 'slide_category': 'infographic',
                 'is_published': True,
             }),
             (0, 0, {
                 'name': 'Mighty Carrots',
                 'sequence': 3,
                 'image_1920': img_content,
                 'slide_category': 'infographic',
                 'is_published': True,
             }),
             (0, 0, {
                 'name':
                 'How to Grow and Harvest The Best Strawberries | Basics',
                 'sequence': 4,
                 'binary_content': pdf_content,
                 'slide_category': 'document',
                 'is_published': True,
             }),
             (0, 0, {
                 'name':
                 'Test your knowledge',
                 'sequence':
                 5,
                 'slide_category':
                 '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,
                         })]
                     })
                 ]
             })]
        })
Example #18
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))
Example #19
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
Example #20
0
 def action_cancel(self, message=None):
     values = {'state': 'canceled', 'schedule_date': Datetime.now()}
     if message:
         values['state_msg'] = message
     self.write(values)
     self.mapped('participant_id').check_completed()
    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
        }
Example #22
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)]

            # get data of stock_history in one shot to speed things up (the view can be very slow)
            stock_history_data = {}
            if stock_history:
                self._cr.execute(
                    """SELECT id, product_id, price_unit_on_quant, company_id, quantity
                                    FROM stock_history WHERE id in %s""",
                    (tuple(stock_history.ids), ))
                stock_history_data = {
                    line['id']: line
                    for line in self._cr.dictfetchall()
                }

            histories_dict = {}
            not_real_cost_method_products = self.env['product.product'].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
                for stock_history in group_lines.get(
                        str(line.get('__domain', domain))):
                    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
Example #23
0
    def _action_open_presence_view(self):
        # Compute the presence/absence for the employees on the same
        # company than the HR/manager. Then opens the kanban view
        # of the employees with an undefined presence/absence

        _logger.info("Employees presence checked by: %s" % self.env.user.name)

        company = self.env.user.company_id
        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()

        return {
            "type": "ir.actions.act_window",
            "res_model": "hr.employee",
            "views": [[self.env.ref('hr_presence.hr_employee_view_kanban').id, "kanban"], [False, "tree"], [False, "form"]],
            'view_mode': 'kanban,tree,form',
            "domain": [],
            "name": "Employee's Presence to Define",
            "context": {'search_default_group_hr_presence_state': 1},
        }
    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')
Example #25
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',
            allocation_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.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')

        # Employee's manager approves
        allocation.with_user(self.user_leave_team_leader).action_approve()
        self.assertEqual(allocation.state, 'validate1')
        self.assertEqual(allocation.first_approver_id,
                         self.user_leave_team_leader.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
        # the "hr_holidays_manager" user need this group to access timesheets of other users
        with additional_groups(self.hr_holidays_manager,
                               'hr_timesheet.group_hr_timesheet_approver'):
            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)
    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}
Example #27
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
    def sync_participants(self):
        """ Creates new participants, taking into account already-existing ones
        as well as campaign filter and unique field. """
        def _uniquify_list(seq):
            seen = set()
            return [x for x in seq if x not in seen and not seen.add(x)]

        participants = self.env['marketing.participant']
        # auto-commit except in testing mode
        auto_commit = not getattr(threading.currentThread(), 'testing', False)
        for campaign in self.filtered(lambda c: c.marketing_activity_ids):
            now = Datetime.now()
            if not campaign.last_sync_date:
                campaign.last_sync_date = now

            RecordModel = self.env[campaign.model_name]

            # Fetch existing participants
            participants_data = participants.search_read(
                [('campaign_id', '=', campaign.id)], ['res_id'])
            existing_rec_ids = _uniquify_list([
                live_participant['res_id']
                for live_participant in participants_data
            ])

            record_domain = literal_eval(campaign.domain or "[]")
            db_rec_ids = _uniquify_list(RecordModel.search(record_domain).ids)
            to_create = [
                rid for rid in db_rec_ids if rid not in existing_rec_ids
            ]  # keep ordered IDs
            to_remove = set(existing_rec_ids) - set(db_rec_ids)
            if campaign.unique_field_id and campaign.unique_field_id.name != 'id':
                without_duplicates = []
                existing_records = RecordModel.with_context(
                    prefetch_fields=False).browse(existing_rec_ids).exists()
                # Split the read in batch of 1000 to avoid the prefetch
                # crawling the cache for the next 1000 records to fetch
                unique_field_vals = {
                    rec[campaign.unique_field_id.name]
                    for index in range(0, len(existing_records), 1000)
                    for rec in existing_records[index:index + 1000]
                }

                for rec in RecordModel.with_context(
                        prefetch_fields=False).browse(to_create):
                    field_val = rec[campaign.unique_field_id.name]
                    # we exclude the empty recordset with the first condition
                    if (not campaign.unique_field_id.relation or
                            field_val) and field_val not in unique_field_vals:
                        without_duplicates.append(rec.id)
                        unique_field_vals.add(field_val)
                to_create = without_duplicates

            BATCH_SIZE = 100
            for index, rec_id in enumerate(to_create, start=1):
                participants |= participants.create({
                    'campaign_id': campaign.id,
                    'res_id': rec_id,
                })
                if not index % BATCH_SIZE and auto_commit:
                    self.env.cr.commit()

            if to_remove:
                participants_to_unlink = participants.search([
                    ('res_id', 'in', list(to_remove)),
                    ('campaign_id', '=', campaign.id),
                    ('state', '!=', 'unlinked'),
                ])
                for index in range(0, len(participants_to_unlink), 1000):
                    participants_to_unlink[index:index +
                                           1000].action_set_unlink()
                    # Commit only every 100 operation to avoid committing to often
                    # this mean every 10k record. It should be ok, it takes 1sec second to process 10k
                    if not index % (BATCH_SIZE * 100):
                        self.env.cr.commit()

        return participants
Example #29
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 literal_eval(self.env['ir.config_parameter'].sudo().get_param(
                'hr.hr_presence_control_ip', 'False')):
            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 literal_eval(self.env['ir.config_parameter'].sudo().get_param(
                'hr.hr_presence_control_email', 'False')):
            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
Example #30
0
    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,
        })
        self.env['ir.property'].create([{
            'name':
            'property_account_receivable_id',
            'fields_id':
            self.env['ir.model.fields'].search(
                [('model', '=', 'res.partner'),
                 ('name', '=', 'property_account_receivable_id')],
                limit=1).id,
            'value':
            'account.account,%s' % (a_recv.id),
            'company_id':
            self.env.company.id,
        }, {
            'name':
            'property_account_payable_id',
            'fields_id':
            self.env['ir.model.fields'].search(
                [('model', '=', 'res.partner'),
                 ('name', '=', 'property_account_payable_id')],
                limit=1).id,
            'value':
            'account.account,%s' % (a_pay.id),
            'company_id':
            self.env.company.id,
        }])

        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',
            'certificate':
            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>",
            'thank_you_message':
            "<p></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',
                 'display_mode':
                 'dropdown',
                 'constr_mandatory':
                 True,
                 'labels_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',
                 'labels_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': 'free_text',
             })]
        })

        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)
Example #31
0
    def action_update_participants(self):
        """ Synchronizes all participants based campaign activities demanding synchronization
        It is done in 2 part:

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

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

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

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

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

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

        self.action_set_synchronized()
Example #32
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()
Example #33
0
    def available_shift_irregular_worker(self,
                                         irregular_enable_sign_up=False,
                                         nexturl=""):
        """
        Return template variables for
        'beesdoo_website_shift.available_shift_irregular_worker_grid'
        """
        # Get current user
        cur_user = request.env["res.users"].browse(request.uid)

        # Get all the shifts in the future with no worker
        shifts = (request.env["beesdoo.shift.shift"].sudo().search(
            [
                ("start_time", ">", Datetime.now()),
                ("worker_id", "=", False),
                ("state", "=", "open"),
            ],
            order="task_template_id, start_time, task_type_id",
        ))

        # Get shifts where user is subscribed
        subscribed_shifts = (request.env["beesdoo.shift.shift"].sudo().search(
            [
                ("start_time", ">", Datetime.now()),
                ("worker_id", "=", cur_user.partner_id.id),
            ],
            order="task_template_id, start_time, task_type_id",
        ))

        # Get config
        highlight_rule_pc = request.website.highlight_rule_pc
        hide_rule = request.website.hide_rule / 100.0

        groupby_iter = groupby(
            shifts,
            lambda s: (s.task_template_id, s.start_time, s.task_type_id),
        )

        displayed_shifts = []
        for keys, grouped_shifts in groupby_iter:
            task_template, start_time, task_type = keys
            shift_list = list(grouped_shifts)
            # Compute available space
            free_space = len(shift_list)
            # Is the current user subscribed to this task_template
            is_subscribed = any((sub_shift.task_template_id == task_template
                                 and sub_shift.start_time == start_time
                                 and sub_shift.task_type_id == task_type)
                                for sub_shift in subscribed_shifts)
            # Check the necessary number of worker based on the
            # highlight_rule_pc
            has_enough_workers = (
                free_space <=
                (task_template.worker_nb * highlight_rule_pc) / 100)
            if free_space >= task_template.worker_nb * hide_rule:
                displayed_shifts.append(
                    DisplayedShift(
                        shift_list[0],
                        free_space,
                        is_subscribed,
                        has_enough_workers,
                    ))

        shift_weeks = build_shift_grid(displayed_shifts)
        return {
            "shift_weeks": shift_weeks,
            "nexturl": nexturl,
            "irregular_enable_sign_up": irregular_enable_sign_up,
        }
Example #34
0
    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))
Example #35
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)
Example #36
0
    def setUpClass(cls):
        super(TestAnalyticSearch, cls).setUpClass()
        cls.purchase_order_model = cls.env['purchase.order']
        partner_model = cls.env['res.partner']
        prod_model = cls.env['product.product']
        analytic_account_model = cls.env['account.analytic.account']
        cls.product_uom_model = cls.env['product.uom']

        pa_dict = {
            'name': 'Partner 1',
            'supplier': True,
        }
        cls.partner = partner_model.create(pa_dict)
        uom_id = cls.product_uom_model.search([('name', '=', 'Unit(s)')])[0].id
        pr_dict = {
            'name': 'Product Test',
            'uom_id': uom_id,
        }
        cls.product = prod_model.create(pr_dict)
        ac_dict = {
            'name': 'account 1',
        }
        cls.analytic_account_1 = \
            analytic_account_model.create(ac_dict)
        ac_dict = {
            'name': 'dummyname',
        }
        cls.analytic_account_2 = \
            analytic_account_model.create(ac_dict)
        # PURCHASE ORDER NUM 1 => account 1
        po_dict = {
            'partner_id':
            cls.partner.id,
            'order_line': [(0, 0, {
                'date_planned': Datetime.now(),
                'name': 'PO01',
                'product_id': cls.product.id,
                'product_uom': uom_id,
                'price_unit': 1,
                'product_qty': 5.0,
                'account_analytic_id': cls.analytic_account_1.id,
            }),
                           (0, 0, {
                               'date_planned': Datetime.now(),
                               'name': 'PO01',
                               'product_id': cls.product.id,
                               'product_uom': uom_id,
                               'price_unit': 1,
                               'product_qty': 5.0,
                               'account_analytic_id':
                               cls.analytic_account_1.id,
                           })],
        }
        cls.purchase_order_1 = cls.purchase_order_model.create(po_dict)

        # PURCHASE ORDER NUM 2 => account 1 and 2
        pa_dict2 = {
            'name': 'Partner 2',
            'supplier': True,
        }
        cls.partner2 = partner_model.create(pa_dict2)
        po_dict2 = {
            'partner_id':
            cls.partner2.id,
            'order_line': [
                (0, 0, {
                    'date_planned': Datetime.now(),
                    'name': 'PO01',
                    'product_id': cls.product.id,
                    'product_uom': uom_id,
                    'price_unit': 1,
                    'product_qty': 5.0,
                    'account_analytic_id': cls.analytic_account_1.id,
                }),
                (0, 0, {
                    'date_planned': Datetime.now(),
                    'name': 'PO01',
                    'product_id': cls.product.id,
                    'product_uom': uom_id,
                    'price_unit': 1,
                    'product_qty': 5.0,
                    'account_analytic_id': cls.analytic_account_2.id,
                }),
            ]
        }
        cls.purchase_order_2 = cls.purchase_order_model.create(po_dict2)
        # PURCHASE ORDER NUM 3 => account 2
        po_dict3 = {
            'partner_id':
            cls.partner2.id,
            'order_line': [
                (0, 0, {
                    'date_planned': Datetime.now(),
                    'name': 'PO01',
                    'product_id': cls.product.id,
                    'product_uom': uom_id,
                    'price_unit': 1,
                    'product_qty': 5.0,
                    'account_analytic_id': cls.analytic_account_2.id,
                }),
                (0, 0, {
                    'date_planned': Datetime.now(),
                    'name': 'PO01',
                    'product_id': cls.product.id,
                    'product_uom': uom_id,
                    'price_unit': 1,
                    'product_qty': 5.0,
                    'account_analytic_id': cls.analytic_account_2.id,
                }),
            ]
        }

        cls.purchase_order_3 = cls.purchase_order_model.create(po_dict3)
Example #37
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)
Example #38
0
    def setUp(self):
        super(TestPurchaseOpenQty, self).setUp()
        self.purchase_order_model = self.env["purchase.order"]
        purchase_order_line_model = self.env["purchase.order.line"]
        partner_model = self.env["res.partner"]
        prod_model = self.env["product.product"]
        analytic_account_model = self.env["account.analytic.account"]

        # partners
        pa_dict = {"name": "Partner 1"}
        self.partner = partner_model.sudo().create(pa_dict)
        pa_dict2 = {"name": "Partner 2"}
        self.partner2 = partner_model.sudo().create(pa_dict2)

        # account
        ac_dict = {"name": "analytic account 1"}
        self.analytic_account_1 = analytic_account_model.sudo().create(ac_dict)

        # Purchase Order Num 1
        po_dict = {"partner_id": self.partner.id}
        self.purchase_order_1 = self.purchase_order_model.create(po_dict)
        uom_id = prod_model.uom_id.search([("name", "=", "Units")], limit=1).id
        pr_dict = {
            "name": "Product Test",
            "uom_id": uom_id,
            "purchase_method": "purchase",
        }
        self.product = prod_model.sudo().create(pr_dict)
        pl_dict1 = {
            "date_planned": Datetime.now(),
            "name": "PO01",
            "order_id": self.purchase_order_1.id,
            "product_id": self.product.id,
            "product_uom": uom_id,
            "price_unit": 1.0,
            "product_qty": 5.0,
            "account_analytic_id": self.analytic_account_1.id,
        }
        self.purchase_order_line_1 = purchase_order_line_model.sudo().create(
            pl_dict1)
        self.purchase_order_1.button_confirm()

        # Purchase Order Num 2
        po_dict2 = {"partner_id": self.partner2.id}
        self.purchase_order_2 = self.purchase_order_model.create(po_dict2)
        pr_dict2 = {
            "name": "Product Test 2",
            "uom_id": uom_id,
            "purchase_method": "receive",
        }
        self.product2 = prod_model.sudo().create(pr_dict2)
        pl_dict2 = {
            "date_planned": Datetime.now(),
            "name": "PO02",
            "order_id": self.purchase_order_2.id,
            "product_id": self.product2.id,
            "product_uom": uom_id,
            "price_unit": 1.0,
            "product_qty": 5.0,
            "account_analytic_id": self.analytic_account_1.id,
        }
        self.purchase_order_line_2 = purchase_order_line_model.sudo().create(
            pl_dict2)
        self.purchase_order_2.button_confirm()
Example #39
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_form = Form(self.env['mrp.production'].sudo(self.user_mrp_user))
        man_order_form.product_id = self.product_4
        man_order_form.bom_id = self.bom_1
        man_order_form.product_uom_id = self.product_4.uom_id
        man_order_form.product_qty = test_quantity
        man_order_form.date_planned_start = test_date_planned
        man_order_form.location_src_id = self.location_1
        man_order_form.location_dest_id = self.warehouse_1.wh_output_stock_loc_id
        man_order = man_order_form.save()

        self.assertEqual(man_order.state, 'draft', "Production order should be in draft state.")
        man_order.action_confirm()
        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.qty_producing = 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.")
Example #40
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'
Example #41
0
    def test_basic(self):
        """ Checks a basic manufacturing order: no routing (thus no workorders), no lot and
        consume strictly what's needed. """
        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_form = Form(self.env['mrp.production'].sudo(self.user_mrp_user))
        man_order_form.product_id = self.product_4
        man_order_form.bom_id = self.bom_1
        man_order_form.product_uom_id = self.product_4.uom_id
        man_order_form.product_qty = test_quantity
        man_order_form.date_planned_start = test_date_planned
        man_order_form.location_src_id = self.location_1
        man_order_form.location_dest_id = self.warehouse_1.wh_output_stock_loc_id
        man_order = man_order_form.save()

        self.assertEqual(man_order.state, 'draft', "Production order should be in draft state.")
        man_order.action_confirm()
        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)

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

        man_order.button_mark_done()
        self.assertEqual(man_order.state, 'done', "Production order should be in done state.")
Example #42
0
    def get_meeting_this_week(
            self, employee,
            index):  # meeting_today = [id(int), [name, start, stop]]
        # tim tat ca cac leave cua nhan vien trong tuan nay
        # tim tat ca cac event duoc tao ra sau khi approve
        # tim tat ca cac meeting trong tuan nay khong nam trong nhung meeting trong buoc tren
        # , ('id', 'not in', leave_ids)
        leaves = request.env['hr.leave'].sudo().search([('state', '=',
                                                         'validate')])
        leave_ids = []
        for e in leaves:
            leave_ids.append(e.meeting_id.id)
        today = Datetime.now()
        start = today - timedelta(days=today.weekday())
        end = start + timedelta(days=6)
        meetings = request.env['calendar.event'].sudo().search([
            ('stop', '>=', str(start)), ('start', '<=', str(end)),
            ('id', 'not in', leave_ids)
        ])
        meeting_this_week_ids = []
        for e in meetings.ids:
            if isinstance(e, int):
                meeting_this_week_ids.append(e)
        # tim tat ca cac meeting employee nay tham gia trong khoang thoi gian tuan nay
        calendar_attendee_this_week = request.env['calendar.attendee'].sudo(
        ).search([('event_id', 'in', meeting_this_week_ids),
                  ('partner_id', '=', employee.user_id.partner_id.id),
                  ('state', '=', 'accepted')])
        # set quyen truy cap tat ca meeting cho admin
        # admin = request.env['res.groups'].sudo().search([('name', '=', "Settings")])
        # set_admin = admin.users
        # loc va return
        check_meeting = []
        meeting_this_week = {}

        for calendar_attendee_this_week_item in calendar_attendee_this_week:
            meeting_today_am = []
            meeting_today_pm = []
            meeting_today = []
            index += 1
            meeting = calendar_attendee_this_week_item.event_id
            if self.user_has_groups('employee_time_table.group_admin_timetable'
                                    ) or self._uid == employee.user_id.id:
                meeting_reason = meeting.name
            else:
                meeting_reason = "Meeting Occupied"
            # fix time zone

            current_meeting_start = meeting.start.astimezone(
                timezone(self.get_timezone()))
            current_meeting_stop = meeting.stop.astimezone(
                timezone(self.get_timezone()))
            meeting_start_standard_visual = current_meeting_start.strftime(
                "%d/%m/%Y %H:%M")
            meeting_stop_standard_visual = current_meeting_stop.strftime(
                "%d/%m/%Y %H:%M")

            # if meeting not all day
            if not meeting.allday:
                # if no, check if meeting occurs in the morning, if yes, update data
                check_meeting.append(
                    meeting.start.astimezone(timezone(
                        self.get_timezone())).weekday())
                meeting_day = current_meeting_start.strftime("%A")
                if int(current_meeting_start.strftime("%H")) < 13 and int(
                        current_meeting_stop.strftime("%H")) < 13:
                    # meeting_day += "_AM"
                    infos = [
                        meeting_reason, meeting_start_standard_visual,
                        meeting_stop_standard_visual
                    ]
                    meeting_today_am.append(True)
                    meeting_today_am.append(False)
                    meeting_today_am.append(meeting.id)
                    meeting_today_am.append(infos)
                    if not meeting_this_week.get(meeting_day):
                        meeting_this_week.update({
                            meeting_day:
                            [True, False, index, [meeting_today_am]]
                        })
                    else:
                        new_meeting_today_data_am = meeting_this_week.get(
                            meeting_day)[3]
                        new_meeting_today_data_am.append(meeting_today_am)
                        meeting_this_week.update({
                            meeting_day: [
                                True,
                                meeting_this_week.get(meeting_day)[1], index,
                                new_meeting_today_data_am
                            ]
                        })

                elif int(current_meeting_start.strftime("%H")) >= 13 and int(
                        current_meeting_stop.strftime("%H")) >= 13:
                    # meeting_day += "_PM"
                    infos = [
                        meeting_reason, meeting_start_standard_visual,
                        meeting_stop_standard_visual
                    ]
                    meeting_today_pm.append(False)
                    meeting_today_pm.append(True)
                    meeting_today_pm.append(meeting.id)
                    meeting_today_pm.append(infos)
                    if not meeting_this_week.get(meeting_day):
                        meeting_this_week.update({
                            meeting_day:
                            [False, True, index, [meeting_today_pm]]
                        })
                    else:
                        new_meeting_today_data_pm = meeting_this_week.get(
                            meeting_day)[3]
                        new_meeting_today_data_pm.append(meeting_today_pm)
                        meeting_this_week.update({
                            meeting_day: [
                                meeting_this_week.get(meeting_day)[0], True,
                                index, new_meeting_today_data_pm
                            ]
                        })
                else:
                    infos = [
                        meeting_reason, meeting_start_standard_visual,
                        meeting_stop_standard_visual
                    ]
                    meeting_today.append(True)
                    meeting_today.append(True)
                    meeting_today.append(meeting.id)
                    meeting_today.append(infos)
                    if not meeting_this_week.get(meeting_day):
                        meeting_this_week.update({
                            meeting_day: [True, True, index, [meeting_today]]
                        })
                    else:
                        new_meeting_today_data = meeting_this_week.get(
                            meeting_day)[3]
                        new_meeting_today_data.append(meeting_today)
                        meeting_this_week.update({
                            meeting_day: [
                                meeting_this_week.get(meeting_day)[0], True,
                                index, new_meeting_today_data
                            ]
                        })
            else:
                current_meeting_start_tmp = meeting.start
                if datetime.strftime(current_meeting_start_tmp,
                                     '%Y/%m/%d') < datetime.strftime(
                                         start, '%Y/%m/%d'):
                    current_meeting_start_tmp = start
                # if not sunday
                monday_first_time = True
                while monday_first_time and current_meeting_start_tmp.weekday(
                ) < 7 and datetime.strftime(current_meeting_start_tmp,
                                            '%Y/%m/%d') <= datetime.strftime(
                                                meeting.stop, '%Y/%m/%d'):
                    current_meeting_day = current_meeting_start_tmp.strftime(
                        "%A")
                    check_meeting.append(current_meeting_start_tmp.weekday())
                    if not meeting_this_week.get(current_meeting_day):
                        meeting_this_week.update({
                            current_meeting_day: [
                                True, True, index,
                                [[
                                    True, True, meeting.id,
                                    [
                                        meeting_reason,
                                        meeting.start.strftime("%d/%m/%Y") +
                                        ' 00:00',
                                        meeting.stop.strftime("%d/%m/%Y") +
                                        ' 23:59'
                                    ]
                                ]]
                            ]
                        })
                    else:
                        meeting_this_week.get(current_meeting_day)[0] = True
                        meeting_this_week.get(current_meeting_day)[1] = True
                        meeting_this_week.get(current_meeting_day)[3].append([
                            True, True, index,
                            [
                                meeting_reason,
                                meeting.start.strftime("%d/%m/%Y") + ' 00:00',
                                meeting.stop.strftime("%d/%m/%Y") + ' 23:59'
                            ]
                        ])
                    index += 1
                    current_meeting_start_tmp += timedelta(days=1)
                    if current_meeting_start_tmp.weekday() == 0:
                        monday_first_time = False

        # if not having meeting, return false

        day_off = 'None'
        for i in range(6):
            if i not in check_meeting:
                if i == 0:
                    day_off = 'Monday'
                if i == 1:
                    day_off = 'Tuesday'
                if i == 2:
                    day_off = 'Wednesday'
                if i == 3:
                    day_off = 'Thursday'
                if i == 4:
                    day_off = 'Friday'
                if i == 5:
                    day_off = 'Saturday'
                meeting_today = []
                meeting_this_week.update(
                    {day_off: [False, False, False, [meeting_today]]})
        return meeting_this_week, index