def _check_quantity(self, active_model): '''Check for groups_id of uid and if it are not merger manager check limit quantity of objects to merge. ''' if len(self._context.get('active_ids', [])) < 2: raise UserError(_('At less two items are necessary for merge.')) model = IrModel.sudo().search([('model', '=', active_model)], limit=1) if model and 0 < model.merge_limit < len( self._context.get('active_ids', [])): raise UserError(_('You can`t merge so much objects at one time.')) return True
def create(self, vals): res = super(WorkDistributorWizard, self).create(vals) active_ids = self.env.context.get('active_ids', False) active_model = self.env.context.get('active_model', False) field = self.env['ir.model.fields'].browse( self.env.context.get('strategy_field_id')) if not active_model: raise Warning(_('Configuration Error!'), _('The is no active model defined!')) self.env[active_model].browse(active_ids).write( {field.name: res.strategy_id.id}) return res
def check_name(self): '''Check name of a CDRIdentifier ''' if not check_identifier(self.name): raise ValidationError( _("Name must be a available python identifier"))
def create_field(self, group_model, model, destination_field): ''' Create field to save which distribution strategy use on each group_field model objects. ''' field_obj = self.env['ir.model.fields'] model_obj = self.env['ir.model'] group_model = model_obj.search([('model', '=', group_model)]) field_base_name = '%s_%s' % (model.model.replace('.', '_'), destination_field.name) field_name = 'x_%s_id' % field_base_name field_data = { 'model': group_model[0].model, 'model_id': group_model.ids[0], 'name': field_name, 'relation': 'work.distribution.strategy', 'field_description': _("Work Distribution Strategy for %s on %s") % (destination_field.field_description, model.name), 'state': 'manual', 'ttype': 'many2one' } new_field = field_obj.create(field_data) self.create_ir_model_data_reference('ir.model.fields', new_field.id, field_name) return new_field.id
def _check_signals(self): '''Check that there is at least some signal. ''' if not all(h.event_raise or h.continue_raising or h.stop_raising for h in self): raise ValidationError(_('At least one signal must be checked.'))
def check_action(self): '''Verify that the action_id is a valid id of the ir.actions.actions model or a valid xml_id. Validates that the action_dict is correctly evaluated as a dictionary in python code. ''' if not (self.action_id or self.action_dict): raise ValidationError(_('Action id or Action dict must be define.')) if self.action_id: try: action = self.env['ir.actions.actions'].browse(int(self.action_id)) if not action.exists(): raise ValidationError('There is no action created with this action_id') except ValueError: try: # Return the record corresponding to the given ``xml_id`` # in this case the xml_id is ``action_id`` action = self.env.ref(self.action_id) action._name.startswith('ir.actions.') except Exception as e: raise ValidationError( 'There is no action created with ' 'this xml_id, remember the structure to invoke ' 'it is addons.xml_id' ) if self.action_dict: try: evaluate(self.action_dict or 'result={}', mode='exec', env=self.env) except Exception as e: raise ValidationError(e.message)
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): res = super(object_merger, self).fields_view_get(view_id, view_type, toolbar=toolbar, submenu=submenu) if view_type == 'form': object_ids = self._context.get('active_ids', []) active_model = self._context['active_model'] if object_ids: self._check_quantity(active_model) field_name = 'x_%s_id' % active_model.replace('.', '_') view_part = """ <field name="{field_name}"/> <separator string="{string}" colspan="4"/> <field name="info" nolabel="1" colspan="4"/> """.format(field_name=field_name, string=_("To merge")) res['arch'] = res['arch'].decode('utf8').replace( """<separator string="to_replace"/>""", view_part) field = self.fields_get([field_name, 'info']) field_data = field[field_name] field_data.update( domain=[('id', '=', object_ids)], selection=self.env[active_model].sudo().name_get(), required=True) res['fields'].update(field) return res
def _do_post_with_celery(self): # Do the real work inside an iterator so that we can use the # until_timeout. def _validate(): report_progress( _("Posting the entries. This may take several " "minutes depending on the length of the entries."), valuemin=0, valuemax=len(self) ) records = self.sorted(lambda invoice: len(get_lines(invoice))) for progress, record in enumerate(records): report_progress(progress=progress) with self.env.cr.savepoint(): # Since the soft time-limit may occur after the first # invoice was validate, but before the second finishes, we # must ensure all DB changes for each invoice is # 'atomically' done or not done at all. perform_post(record) yield record def count(iterable): result = 0 for _x in iterable: # noqa: F402 result += 1 return result res = count(until_timeout(_validate())) if not res: raise ValidationError(_("No entry could be posted")) else: return CLOSE_PROGRESS_BAR
def _check_definition(self): for record in self: try: record._evaluate() except Exception as e: raise exceptions.ValidationError( _("Wrong definition: %s") % e.message)
def default_get(self, fields_list): values = super(WorkDistributorWizard, self).default_get(fields_list) if 'info' in fields_list: active_ids = self.env.context.get('active_ids', False) active_model = self.env.context.get('active_model', False) ir_model = self.env['ir.model'] model = ir_model.search([('model', '=', active_model)])[0] field = self.env['ir.model.fields'].browse( self.env.context.get('strategy_field_id')) names = [_('%s\n Strategy: %s') % (item.name_get()[0][1], getattr(item, field.name).name or '') for item in self.env[active_model].browse(active_ids)] info = _("%s(s) to set work distribution strategy:\n" " * %s") % (model.name, '\n * '.join(names)) values.update({'info': info}) return values
def _get_price_field_get(self): PriceType = self.env['product.price.type'] types = PriceType.search([]) result = [] for line in types: result.append((line.field, line.name)) result.append(('pricelist', _('Other Pricelist'))) return result
def action_merge(self): active_model = self._context.get('active_model') if not active_model: raise UserError(_('The is no active model defined!')) Model = self.env[active_model] sources = Model.browse(self._context.get('active_ids', [])) attr = self._context.get('field_to_read') val = getattr(self, attr, None) if attr else None if not val: raise UserError(_('Please select one value to keep')) target = val[0] self.merge(sources, target) try: Model.read([]) return target.get_formview_action() except AccessError: return CLOSE_WINDOW
def _check_signals(self): '''Verify that at least one sign must be checked. ''' if not all(h.event_raise or h.continue_raising or h.stop_raising for h in self): raise exceptions.ValidationError( _('At least one signal must be checked.'))
def _check_recipients(self): '''Restrict the use of at least one recipient.These recipients are the result of the defined domain. ''' if not all(handler.recipients for handler in self): raise ValidationError( _('At least one recipient is necessary.'))
def send_mail(self, **kwargs): # Odoo 10 introduced auto_commit '''Validate no readonly token was modified and remove added style. ''' self.ensure_one() if self._validate_template_restrictions(): return super(MailComposeMessage, self).send_mail(**kwargs) else: raise ValidationError(_('Non-editable items were modified.'))
def onchange_use_domain_builder(self): ''' If the domain constructor changes it assigns default values to the domain. By default use_domain_builder is 'True'. ''' if self.use_domain_builder: self.build_domain = '' self.domain = '' else: self.domain = (self.build_domain or '') + _(DOMAIN_DEFAULT)
def merge(self): """Merge several `partners` into a single destination partner. Original `partners` will be removed from the DB afterwards. Only target will remain. All references to the original partners will be re-establish to the target partner. If `partners` constains less that 2 partners, do nothing. All partners must have the same email. If sources `partner` is none, the target partner defaults to the last created record in `partners`. :param sources: The source partners. :type sources: A recordset of 'res.partners'. :param target: The target partner. :type target: A singleton recordset of 'res.partners' or None. """ sources = self.partner_ids target = self.dest_partner_id if sources.sudo().exists() and len(sources) < 2: raise UserError(_("Constains less that 2 partners, do nothing")) partner_different_emails = { p.email for p in sources if p.email and p.email.strip() } if len(partner_different_emails) > 1: user = self.env.user if user.has_group('xopgi_partner_merge.base_parter_merger'): object_merger = self.env['object.merger'] object_merger.merge(sources, target) else: raise UserError( _("All contacts must have the same email. Only the " "users with Partner Merge rights can merge contacts " "with different emails.") ) object_merger = self.env['object.merger'] object_merger.merge(sources, target) self.unlink()
def onchange_strategy_ids(self): ''' When the selected strategies change, it is validated that the field 'Other field' maintains the structure of a dictionary that its values are valid. ''' warning = False try: other_fields = safe_eval(self.other_fields or '{}') except (ValueError, SyntaxError, ): other_fields = {} warning = { 'title': _('Warning!'), 'message': _('Other fields must be a python dict.') } fields_name = self.strategy_ids.get_fields_name() other_fields.update({n: n for n in fields_name - set(other_fields)}) self.other_fields = str(other_fields) return {'warning': warning} if warning else None
def _check_definition(self): '''Check the control variable definition. ''' for variable in self: try: variable.template.compile(variable.arguments) except Exception as e: raise exceptions.ValidationError( _("Wrong definition: %s") % e.message )
def _check_strategy_ids(self): '''Validate that when no group field is defined, only one strategy can be selected. ''' for model in self: if not model.group_field and len(model.strategy_ids) > 1: raise ValidationError( _('When no group field is defined only one strategy ' 'must be selected.')) return True
def validate_type_alias(self, vals, use_lead, use_opportunity): alias = eval(vals['alias_defaults']) type_valias = alias.get('type', False) if not type_valias: return vals if use_lead is None: use_lead = self.use_leads if use_opportunity is None: use_opportunity = self.use_opportunities if not use_lead and type_valias == 'lead': raise UserError( _("This sale team not use 'Leads' then cant alias with " "'Lead'. Please select the 'Leads' option from " "'Sales team'")) if not use_opportunity and type_valias == 'opportunity': raise UserError( _("This sale team not use 'Opportunities' then cant alias with " "'Opportunity' please select the Opportunities' option from " "'Sales team'.")) return vals
def _create_statement(self): '''Create a Bank Statement from payments. Each line in the statement will correspond to each payment (self). All lines will be conciliated with the corresponding payments. The statement is not completed to have starting/ending balances. ''' payments = self.filtered(lambda p: p.should_reconcile_with_statement) if not payments: raise UserError( _("You must select at least a payment that needs reconciliation" )) journal = payments.mapped('journal_id') if len(journal) > 1: raise UserError( _('You cannot create an statement from payments in different ' 'journals.')) Statement = self.env['account.bank.statement'] lines = payments._new_related_statement_lines() statement = Statement.create({ 'date': fields.Date.context_today(self), 'state': 'open', 'name': _('New bank statement'), 'journal_id': journal.id, 'user_id': self.env.user.id, 'line_ids': lines, 'balance_start': Statement.with_context( default_journal_id=journal.id)._default_opening_balance() }) statement.line_ids._reconcile_from_payments() statement.balance_end_real = statement.balance_end return statement
def _check_other_fields(self): ''' Validates that the field names defined in the 'other_field' dictionary are among the names of the fields defined for the selected strategy. And that the defined fields are in some existing model. ''' for model in self: fields_name = model.strategy_ids.get_fields_name() if fields_name: other_fields = safe_eval(model.other_fields or '{}') if not other_fields or not all( other_fields.get(f, False) for f in fields_name): raise ValidationError( _('Other fields must define all fields used on ' 'selected strategies.')) obj = self.env[model.model.model] for field in other_fields.itervalues(): if not obj or not obj._fields.get(field, False): raise ValidationError( _('Some Other fields defined not exist on ' 'destination model')) return True
def _check_definition(self): '''Evaluate and verify the definition of an evidence. ''' for record in self: try: # TODO: Compile only definition_res = record._evaluate() record.evaluate_bool_expresion(definition_res) except Exception as e: raise exceptions.ValidationError( _("Wrong definition: %s") % e.message)
def install_fuzzy_extension(self): try: # TODO: This is bound to fail if the user is not a # super-user... Check with the PostgreSQL documentation for # details. self._cr.execute('CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;') except Exception as error: _logger.error("%s", error) raise UserError( _('A required DB extension was not found. ' 'Ask your administrator to install ' '"postgresql-contrib" package.'))
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): if self._uid != SUPERUSER_ID and not self.env['res.users'].has_group( 'xopgi_mail_move_message.group_move_message'): raise AccessError(_('Access denied.')) result = super(MoveMessageWizard, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) return result
def validate_model_project(self, vals, use_issue, use_task): """Validate that when creating a mail_alias within a project is not created or modified with a model (Task, Issues) without being defined for that project that can use Task and Issues. """ model_id = vals.get('alias_model_id', False) if not model_id: return vals if use_issue is None: use_issue = self.use_issues if use_task is None: use_task = self.use_tasks if not use_issue and model_id == _get_model_ids( self, ['project.issue']).id: raise UserError( _("This project not use 'Issues' then cant alias with 'project.issue'" " please select the 'Isuues option' from the project form.")) if not use_task and model_id == _get_model_ids(self, ['project.task']).id: raise UserError( _("This project not use 'Tasks' then cant alias with 'project.task'" " please select the 'Tasks option' from the project form.")) return vals
def _supplier_invoice_generator(self, partner, account, analytic_account_ids): d = date.today() company = self._context.get('company_id', self.env.user.company_id) journal = self.env['account.journal'].search( [('type', '=', 'purchase'), ('company_id', '=', company.id)], limit=1) # The context allows Odoo to compute the defaults we're missing here. result = Invoice.sudo().with_context(journal_id=journal.id).create( dict( partner_id=partner.id, account_id=account.id, type='in_invoice', # supplier invoice name=_(u"Commission. ") + safe_decode(d.strftime("%B")) + u" / " + safe_decode(partner.name), origin=_(u"Commission. ") + safe_decode(d.strftime("%B")) + u" / " + safe_decode(partner.name), journal_id=journal.id, invoice_line_ids=[ CREATE_RELATED(quantity=1, account_analytic_id=analytic_account.id, name=_("Operation") + safe_decode(analytic_account.name), price_unit=analytic_account.commission) for analytic_account in analytic_account_ids ])) analytic_account_ids.write(dict(supplier_invoice_id=result.id)) followers = [partner.id] employees = self.env["hr.employee"].search([("user_id.partner_id", "=", partner.id)]) for employee in employees: if employee.parent_id: manager = employee.parent_id.user_id.partner_id if any(manager): followers.append(manager.id) result.message_subscribe(partner_ids=followers) return result
def message_post(self, **kwargs): '''Post the bounce to the proper thread. Format bounce notification before posting. ''' data = self._ids[0] message_id, model, thread_id, recipient, rfc_message = data.args subject = rfc_message['subject'] if subject: kwargs['subject'] = subject + _(' -- Detected as bounce') else: kwargs['subject'] = _('Mail Returned to Sender') part = find_part(rfc_message) if part: encoding = part.get_content_charset() # None if attachment kwargs['body'] = tools.append_content_to_html( '', tools.ustr(part.get_payload(decode=True), encoding, errors='replace'), preserve=True) return super(MailBounce, self).message_post(**kwargs)
def _validate(): report_progress(_( "Validating the invoices. This may take several " "minutes depending on the length of the invoices "), valuemin=0, valuemax=len(self)) records = self.sorted(lambda invoice: len(get_lines(invoice))) for progress, record in enumerate(records): report_progress(progress=progress) with self.env.cr.savepoint(): # Since the soft time-limit may occur after the first # invoice was validate, but before the second finishes, we # must ensure all DB changes for each invoice is # 'atomically' done or not done at all. perform_validate(record) yield record