示例#1
0
 def read_group(self,
                domain,
                fields,
                groupby,
                offset=0,
                limit=None,
                orderby=False,
                lazy=True):
     """Override read_group to add res_field=False in domain if not present."""
     if not fields:
         raise AccessError(
             _("Sorry, you must provide fields to read on attachments"))
     if any('(' in field for field in fields + groupby):
         raise AccessError(
             _("Sorry, the syntax 'name:agg(field)' is not available for attachments"
               ))
     if not any(item[0] in ('id', 'res_field') for item in domain):
         domain.insert(0, ('res_field', '=', False))
     groupby = [groupby] if isinstance(groupby, str) else groupby
     allowed_fields = self._read_group_allowed_fields()
     fields_set = set(field.split(':')[0] for field in fields + groupby)
     if not self.env.is_system() and (
             not fields or fields_set.difference(allowed_fields)):
         raise AccessError(
             _("Sorry, you are not allowed to access these fields on attachments."
               ))
     return super().read_group(domain,
                               fields,
                               groupby,
                               offset=offset,
                               limit=limit,
                               orderby=orderby,
                               lazy=lazy)
示例#2
0
    def migrate_to_lobject(self):
        """migrates all binary attachments to postgres large object storage"""
        if not self.env.user._is_admin():
            raise AccessError(
                _('Only administrators can execute this action.'))

        atts = self.search([
            '&',
            '&',
            ('id', '>', 0),  # bypass filtering of field-attached attachments
            ('type', '=', 'binary'),
            '|',
            ('store_fname', '=', False),
            ('store_fname', 'not like', LARGE_OBJECT_LOCATION + ':%')
        ])

        att_count = len(atts)
        if att_count:
            log.info(
                f'Migrating {att_count} database attachments to Large Objects...'
            )
            if self._storage() != LARGE_OBJECT_LOCATION:
                raise Exception(
                    f'Default storage is not set to Large Object ({LARGE_OBJECT_LOCATION})'
                )
            current_att = 1
            for att in atts:
                log.info(
                    f'Migrating attachment ID {att.id} ({current_att} of {att_count})...'
                )
                # re-save data to move to lobject storage
                att.write({'mimetype': att.mimetype, 'datas': att.datas})
                current_att += 1
示例#3
0
文件: digest.py 项目: marionumza/saas
 def _compute_kpi_hr_recruitment_new_colleagues_value(self):
     if not self.env.user.has_group('hr_recruitment.group_hr_recruitment_user'):
         raise AccessError(_("Do not have access, skip this data for user's digest email"))
     for record in self:
         start, end, company = record._get_kpi_compute_parameters()
         new_colleagues = self.env['hr.employee'].search_count([
             ('create_date', '>=', start),
             ('create_date', '<', end),
             ('company_id', '=', company.id)
         ])
         record.kpi_hr_recruitment_new_colleagues_value = new_colleagues
示例#4
0
    def _parse_import_data_recursive(self, model, prefix, data, import_fields,
                                     options):
        # Get fields of type date/datetime
        all_fields = self.env[model].fields_get()
        for name, field in all_fields.items():
            name = prefix + name
            if field['type'] in ('date', 'datetime') and name in import_fields:
                index = import_fields.index(name)
                self._parse_date_from_data(data, index, name, field['type'],
                                           options)
            # Check if the field is in import_field and is a relational (followed by /)
            # Also verify that the field name exactly match the import_field at the correct level.
            elif any(name + '/' in import_field
                     and name == import_field.split('/')[prefix.count('/')]
                     for import_field in import_fields):
                # Recursive call with the relational as new model and add the field name to the prefix
                self._parse_import_data_recursive(field['relation'],
                                                  name + '/', data,
                                                  import_fields, options)
            elif field['type'] in ('float',
                                   'monetary') and name in import_fields:
                # Parse float, sometimes float values from file have currency symbol or () to denote a negative value
                # We should be able to manage both case
                index = import_fields.index(name)
                self._parse_float_from_data(data, index, name, options)
            elif field['type'] == 'binary' and field.get('attachment') and any(
                    f in name for f in IMAGE_FIELDS) and name in import_fields:
                index = import_fields.index(name)

                with requests.Session() as session:
                    session.stream = True

                    for num, line in enumerate(data):
                        if re.match(
                                config.get("import_image_regex",
                                           DEFAULT_IMAGE_REGEX), line[index]):
                            if not self.env.user._can_import_remote_urls():
                                raise AccessError(
                                    _("You can not import images via URL, check with your administrator or support for the reason."
                                      ))

                            line[index] = self._import_image_by_url(
                                line[index], session, name, num)
                        else:
                            try:
                                base64.b64decode(line[index], validate=True)
                            except binascii.Error:
                                raise ValueError(
                                    _("Found invalid image data, images should be imported as either URLs or base64-encoded data."
                                      ))

        return data
示例#5
0
    def run(self):
        """ Runs the server action. For each server action, the
        run_action_<STATE> method is called. This allows easy overriding
        of the server actions.

        :param dict context: context should contain following keys

                             - active_id: id of the current object (single mode)
                             - active_model: current model that should equal the action's model

                             The following keys are optional:

                             - active_ids: ids of the current records (mass mode). If active_ids
                               and active_id are present, active_ids is given precedence.

        :return: an action_id to be executed, or False is finished correctly without
                 return action
        """
        res = False
        for action in self:
            action_groups = action.groups_id
            if action_groups and not (action_groups & self.env.user.groups_id):
                raise AccessError(
                    _("You don't have enough access rights to run this action."
                      ))

            eval_context = self._get_eval_context(action)
            if hasattr(self, 'run_action_%s_multi' % action.state):
                # call the multi method
                run_self = self.with_context(eval_context['env'].context)
                func = getattr(run_self, 'run_action_%s_multi' % action.state)
                res = func(action, eval_context=eval_context)

            elif hasattr(self, 'run_action_%s' % action.state):
                active_id = self._context.get('active_id')
                if not active_id and self._context.get('onchange_self'):
                    active_id = self._context['onchange_self']._origin.id
                    if not active_id:  # onchange on new record
                        func = getattr(self, 'run_action_%s' % action.state)
                        res = func(action, eval_context=eval_context)
                active_ids = self._context.get(
                    'active_ids', [active_id] if active_id else [])
                for active_id in active_ids:
                    # run context dedicated to a particular active_id
                    run_self = self.with_context(active_ids=[active_id],
                                                 active_id=active_id)
                    eval_context["env"].context = run_self._context
                    # call the single method related to the action: run_action_<STATE>
                    func = getattr(run_self, 'run_action_%s' % action.state)
                    res = func(action, eval_context=eval_context)
        return res or False
示例#6
0
文件: digest.py 项目: marionumza/saas
 def _compute_kpi_website_sale_total_value(self):
     if not self.env.user.has_group(
             'sales_team.group_sale_salesman_all_leads'):
         raise AccessError(
             _("Do not have access, skip this data for user's digest email")
         )
     for record in self:
         start, end, company = record._get_kpi_compute_parameters()
         confirmed_website_sales = self.env['sale.order'].search([
             ('date_order', '>=', start), ('date_order', '<', end),
             ('state', 'not in', ['draft', 'cancel', 'sent']),
             ('website_id', '!=', False), ('company_id', '=', company.id)
         ])
         record.kpi_website_sale_total_value = sum(
             confirmed_website_sales.mapped('amount_total'))
示例#7
0
    def force_storage(self):
        """Force all attachments to be stored in the currently configured storage"""
        if not self.env.is_admin():
            raise AccessError(
                _('Only administrators can execute this action.'))

        # domain to retrieve the attachments to migrate
        domain = {
            'db': [('store_fname', '!=', False)],
            'file': [('db_datas', '!=', False)],
        }[self._storage()]

        for attach in self.search(domain):
            attach.write({'datas': attach.datas})
        return True
示例#8
0
 def check_access_rule(self, operation):
     """ Add Access rules of mail.message for non-employee user:
         - read:
             - raise if the type is comment and subtype NULL (internal note)
     """
     if self.user_has_groups('base.group_public'):
         self.env.cr.execute(
             'SELECT id FROM "%s" WHERE website_published IS NOT TRUE AND id = ANY (%%s)'
             % (self._table), (self.ids, ))
         if self.env.cr.fetchall():
             raise AccessError(
                 _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)'
                   ) % (self._description, operation) +
                 ' - ({} {}, {} {})'.format(_('Records:'), self.ids[:6],
                                            _('User:'), self._uid))
     return super(MailMessage, self).check_access_rule(operation=operation)
示例#9
0
    def write(self, vals):
        """
        Synchronize user and its related employee
        and check access rights if employees are not allowed to update
        their own data (otherwise sudo is applied for self data).
        """
        hr_fields = {
            field
            for field_name, field in self._fields.items()
            if field.related_field and field.related_field.model_name ==
            'hr.employee' and field_name in vals
        }
        can_edit_self = self.env['ir.config_parameter'].sudo().get_param(
            'hr.hr_employee_self_edit') or self.env.user.has_group(
                'hr.group_hr_user')
        if hr_fields and not can_edit_self:
            # Raise meaningful error message
            raise AccessError(
                _("You are only allowed to update your preferences. Please contact a HR officer to update other informations."
                  ))

        result = super(User, self).write(vals)

        employee_values = {}
        for fname in [
                f for f in ['name', 'email', 'image_1920', 'tz'] if f in vals
        ]:
            employee_values[fname] = vals[fname]
        if employee_values:
            if 'email' in employee_values:
                employee_values['work_email'] = employee_values.pop('email')
            if 'image_1920' in vals:
                without_image = self.env['hr.employee'].sudo().search([
                    ('user_id', 'in', self.ids), ('image_1920', '=', False)
                ])
                with_image = self.env['hr.employee'].sudo().search([
                    ('user_id', 'in', self.ids), ('image_1920', '!=', False)
                ])
                without_image.write(employee_values)
                if not can_edit_self:
                    employee_values.pop('image_1920')
                with_image.write(employee_values)
            else:
                self.env['hr.employee'].sudo().search([
                    ('user_id', 'in', self.ids)
                ]).write(employee_values)
        return result
示例#10
0
 def _compute_kpi_sale_total_value(self):
     if not self.env.user.has_group(
             'sales_team.group_sale_salesman_all_leads'):
         raise AccessError(
             _("Do not have access, skip this data for user's digest email")
         )
     for record in self:
         start, end, company = record._get_kpi_compute_parameters()
         all_channels_sales = self.env['sale.report'].read_group(
             [('date', '>=', start), ('date', '<', end),
              ('state', 'not in', ['draft', 'cancel', 'sent']),
              ('company_id', '=', company.id)], ['price_total'],
             ['price_total'])
         record.kpi_all_sale_total_value = sum([
             channel_sale['price_total']
             for channel_sale in all_channels_sales
         ])