def validate_iban(iban): iban = normalize_iban(iban) if not iban: raise ValidationError(_("There is no IBAN code.")) country_code = iban[:2].lower() if country_code not in _map_iban_template: raise ValidationError( _("The IBAN is invalid, it should begin with the country code")) iban_template = _map_iban_template[country_code] if len(iban) != len(iban_template.replace(' ', '')): raise ValidationError( _("The IBAN does not seem to be correct. You should have entered something like this %s\n" "Where B = National bank code, S = Branch code, C = Account No, k = Check digit" ) % iban_template) check_chars = iban[4:] + iban[:4] digits = int(''.join( str(int(char, 36)) for char in check_chars)) # BASE 36: 0..9,A..Z -> 0..35 if digits % 97 != 1: raise ValidationError( _("This IBAN does not pass the validation check, please verify it." ))
def _check_pattern(self): for rule in self: p = rule.pattern.replace("\\\\", "X").replace("\{", "X").replace("\}", "X") findall = re.findall("[{]|[}]", p) # p does not contain escaped { or } if len(findall) == 2: if not re.search("[{][N]*[D]*[}]", p): raise ValidationError( _("There is a syntax error in the barcode pattern ") + rule.pattern + _(": braces can only contain N's followed by D's.")) elif re.search("[{][}]", p): raise ValidationError( _("There is a syntax error in the barcode pattern ") + rule.pattern + _(": empty braces.")) elif len(findall) != 0: raise ValidationError( _("There is a syntax error in the barcode pattern ") + rule.pattern + _(": a rule can only contain one pair of braces.")) elif p == '*': raise ValidationError( _(" '*' is not a valid Regex Barcode Pattern. Did you mean '.*' ?" ))
def _check_company_id(self): for template in self: companies = template.mapped('sale_order_template_line_ids.product_id.company_id') | template.mapped('sale_order_template_option_ids.product_id.company_id') if len(companies) > 1: raise ValidationError(_("Your template cannot contain products from multiple companies.")) elif companies and companies != template.company_id: raise ValidationError((_("Your template contains products from company %s whereas your template belongs to company %s. \n Please change the company of your template or remove the products from other companies.") % (companies.mapped('display_name'), template.company_id.display_name)))
def set(self, model_name, field_name, value, user_id=False, company_id=False, condition=False): """ Defines a default value for the given field. Any entry for the same scope (field, user, company) will be replaced. The value is encoded in JSON to be stored to the database. :param user_id: may be ``False`` for all users, ``True`` for the current user, or any user id :param company_id: may be ``False`` for all companies, ``True`` for the current user's company, or any company id :param condition: optional condition that restricts the applicability of the default value; this is an opaque string, but the client typically uses single-field conditions in the form ``'key=val'``. """ if user_id is True: user_id = self.env.uid if company_id is True: company_id = self.env.company.id # check consistency of model_name, field_name, and value try: model = self.env[model_name] field = model._fields[field_name] field.convert_to_cache(value, model) json_value = json.dumps(value, ensure_ascii=False) except KeyError: raise ValidationError( _("Invalid field %s.%s") % (model_name, field_name)) except Exception: raise ValidationError( _("Invalid value for %s.%s: %s") % (model_name, field_name, value)) # update existing default for the same scope, or create one field = self.env['ir.model.fields']._get(model_name, field_name) default = self.search([ ('field_id', '=', field.id), ('user_id', '=', user_id), ('company_id', '=', company_id), ('condition', '=', condition), ]) if default: default.write({'json_value': json_value}) else: self.create({ 'field_id': field.id, 'user_id': user_id, 'company_id': company_id, 'condition': condition, 'json_value': json_value, }) return True
def _check_days(self): for term_line in self: if term_line.option in ('day_following_month', 'day_current_month' ) and term_line.days <= 0: raise ValidationError( _("The day of the month used for this term must be strictly positive." )) elif term_line.days < 0: raise ValidationError( _("The number of days used for a payment term cannot be negative." ))
def _check_sale_line_type(self): for project in self: if project.billable_type == 'task_rate': if project.sale_line_id and not project.sale_line_id.is_service: raise ValidationError( _("A billable project should be linked to a Sales Order Item having a Service product." )) if project.sale_line_id and project.sale_line_id.is_expense: raise ValidationError( _("A billable project should be linked to a Sales Order Item that does not come from an expense or a vendor bill." ))
def _check_lines(self): for terms in self: payment_term_lines = terms.line_ids.sorted() if payment_term_lines and payment_term_lines[-1].value != 'balance': raise ValidationError( _('The last line of a Payment Term should have the Balance type.' )) lines = terms.line_ids.filtered(lambda r: r.value == 'balance') if len(lines) > 1: raise ValidationError( _('A Payment Term should have only one line of type Balance.' ))
def _check_grouping(self): warning = _( 'The Separator Format should be like [,n] where 0 < n :starting from Unit digit. ' '-1 will end the separation. e.g. [3,2,-1] will represent 106500 to be 1,06,500;' '[1,2,-1] will represent it to be 106,50,0;[3] will represent it as 106,500. ' 'Provided as the thousand separator in each case.') for lang in self: try: if not all( isinstance(x, int) for x in json.loads(lang.grouping)): raise ValidationError(warning) except Exception: raise ValidationError(warning)
def _check_product_consistency(self): for item in self: if item.applied_on == "2_product_category" and not item.categ_id: raise ValidationError( _("Please specify the category for which this rule should be applied" )) elif item.applied_on == "1_product" and not item.product_tmpl_id: raise ValidationError( _("Please specify the product for which this rule should be applied" )) elif item.applied_on == "0_product_variant" and not item.product_id: raise ValidationError( _("Please specify the product variant for which this rule should be applied" ))
def _check_valid_values(self): for ptal in self: if ptal.active and not ptal.value_ids: raise ValidationError( _("The attribute %s must have at least one value for the product %s.") % (ptal.attribute_id.display_name, ptal.product_tmpl_id.display_name) ) for pav in ptal.value_ids: if pav.attribute_id != ptal.attribute_id: raise ValidationError( _("On the product %s you cannot associate the value %s with the attribute %s because they do not match.") % (ptal.product_tmpl_id.display_name, pav.display_name, ptal.attribute_id.display_name) ) return True
def _set_check_next_number(self): for journal in self: if journal.check_next_number and not re.match( r'^[0-9]+$', journal.check_next_number): raise ValidationError( _('Next Check Number should only contains numbers.')) if int(journal.check_next_number ) < journal.check_sequence_id.number_next_actual: raise ValidationError( _("The last check number was %s. In order to avoid a check being rejected " "by the bank, you can only use a greater number.") % journal.check_sequence_id.number_next_actual) if journal.check_sequence_id: journal.check_sequence_id.sudo().number_next_actual = int( journal.check_next_number)
def _check_invoice_type_document_type(self): for rec in self.filtered('l10n_latam_document_type_id.internal_type'): internal_type = rec.l10n_latam_document_type_id.internal_type invoice_type = rec.type if internal_type in ['debit_note', 'invoice'] and invoice_type in [ 'out_refund', 'in_refund' ]: raise ValidationError( _('You can not use a %s document type with a refund invoice' ) % internal_type) elif internal_type == 'credit_note' and invoice_type in [ 'out_invoice', 'in_invoice' ]: raise ValidationError( _('You can not use a %s document type with a invoice') % (internal_type))
def _check_current_contract(self): """ Two contracts in state [incoming | open | close] cannot overlap """ for contract in self.filtered( lambda c: c.state not in ['draft', 'cancel'] or c.state == 'draft' and c.kanban_state == 'done'): domain = [ ('id', '!=', contract.id), ('employee_id', '=', contract.employee_id.id), '|', ('state', 'in', ['open', 'close']), '&', ('state', '=', 'draft'), ('kanban_state', '=', 'done') # replaces incoming ] if not contract.date_end: start_domain = [] end_domain = [ '|', ('date_end', '>=', contract.date_start), ('date_end', '=', False) ] else: start_domain = [('date_start', '<=', contract.date_end)] end_domain = [ '|', ('date_end', '>', contract.date_start), ('date_end', '=', False) ] domain = expression.AND([domain, start_domain, end_domain]) if self.search_count(domain): raise ValidationError( _('An employee can only have one contract at the same time. (Excluding Draft and Cancelled contracts)' ))
def write(self, vals): res = super(ModelChildM2o, self).write(vals) if self.name == 'A': raise ValidationError( 'the first existing child should not be changed when adding a new child to the parent' ) return res
def _check_valid_values(self): for ptav in self: if ptav.product_attribute_value_id not in ptav.attribute_line_id.value_ids: raise ValidationError( _("The value %s is not defined for the attribute %s on the product %s.") % (ptav.product_attribute_value_id.display_name, ptav.attribute_id.display_name, ptav.product_tmpl_id.display_name) )
def _check_promo_code_constraint(self): """ Program code must be unique """ for program in self.filtered(lambda p: p.promo_code): domain = [('id', '!=', program.id), ('promo_code', '=', program.promo_code)] if self.search(domain): raise ValidationError(_('The program code must be unique!'))
def l10n_in_check_vat(self): for partner in self.filtered( lambda p: p.commercial_partner_id.country_id.code == 'IN' and p .vat and len(p.vat) != 15): raise ValidationError( _('The GSTIN [%s] for partner [%s] should be 15 characters only.' ) % (partner.vat, partner.name))
def _check_lot_product(self): for line in self: if line.lot_id and line.product_id != line.lot_id.sudo( ).product_id: raise ValidationError( _('This lot %s is incompatible with this product %s' % (line.lot_id.name, line.product_id.display_name)))
def check_vat(self): if self.env.context.get('company_id'): company = self.env['res.company'].browse( self.env.context['company_id']) else: company = self.env.company if company.vat_check_vies: # force full VIES online check check_func = self.vies_vat_check else: # quick and partial off-line checksum validation check_func = self.simple_vat_check for partner in self: if not partner.vat: continue #check with country code as prefix of the TIN vat_country, vat_number = self._split_vat(partner.vat) if not check_func(vat_country, vat_number): #if fails, check with country code from country country_code = partner.commercial_partner_id.country_id.code if country_code: if not check_func(country_code.lower(), partner.vat): msg = partner._construct_constraint_msg( country_code.lower()) raise ValidationError(msg)
def _check_aba_routing(self): for bank in self: if bank.aba_routing and not re.match(r'^\d{1,9}$', bank.aba_routing): raise ValidationError( _('ABA/Routing should only contains numbers (maximum 9 digits).' ))
def _check_l10n_latam_documents(self): validated_invoices = self.filtered(lambda x: x.l10n_latam_use_documents and x.state in ['open', 'done']) without_doc_type = validated_invoices.filtered( lambda x: not x.l10n_latam_document_type_id) if without_doc_type: raise ValidationError( _('The journal require a document type but not document type has been selected on invoices %s.' % (without_doc_type.ids))) without_number = validated_invoices.filtered( lambda x: not x.l10n_latam_document_number and not x. l10n_latam_sequence_id) if without_number: raise ValidationError( _('Please set the document number on the following invoices %s.' % (without_number.ids)))
def _check_product_id(self): """ As no quants are created for consumable products, it should not be possible do adjust their quantity. """ for line in self: if line.product_id.type != 'product': raise ValidationError(_("You can only adjust storable products.") + '\n\n%s -> %s' % (line.product_id.display_name, line.product_id.type))
def _check_validity_dates(self): for leave_type in self: if leave_type.validity_start and leave_type.validity_stop and \ leave_type.validity_start > leave_type.validity_stop: raise ValidationError( _("End of validity period should be greater than start of validity period" ))
def _check_bom_lines(self): for bom in self: for bom_line in bom.bom_line_ids: if bom.product_id and bom_line.product_id == bom.product_id: raise ValidationError(_("BoM line product %s should not be the same as BoM product.") % bom.display_name) if bom_line.product_tmpl_id == bom.product_tmpl_id: raise ValidationError(_("BoM line product %s should not be the same as BoM product.") % bom.display_name) if bom.product_id and bom_line.bom_product_template_attribute_value_ids: raise ValidationError(_("BoM cannot concern product %s and have a line with attributes (%s) at the same time.") % (bom.product_id.display_name, ", ".join([ptav.display_name for ptav in bom_line.bom_product_template_attribute_value_ids]))) for ptav in bom_line.bom_product_template_attribute_value_ids: if ptav.product_tmpl_id != bom.product_tmpl_id: raise ValidationError( _("The attribute value %s set on product %s does not match the BoM product %s.") % (ptav.display_name, ptav.product_tmpl_id.display_name, bom_line.parent_product_tmpl_id.display_name) )
def _check_timesheet_generate(self): for holiday_status in self: if holiday_status.timesheet_generate: if not holiday_status.timesheet_project_id or not holiday_status.timesheet_task_id: raise ValidationError( _("Both the internal project and task are required to " "generate a timesheet for the time off. If you don't want a timesheet, you should " "leave the internal project and task empty."))
def _check_sale_line_type(self): for task in self.sudo(): if task.sale_line_id: if not task.sale_line_id.is_service or task.sale_line_id.is_expense: raise ValidationError( _('You cannot link the order item %s - %s to this task because it is a re-invoiced expense.' % (task.sale_line_id.order_id.id, task.sale_line_id.product_id.name)))
def _check_leave_timesheet_project_id_company(self): for company in self: if company.leave_timesheet_project_id: if company.leave_timesheet_project_id.sudo( ).company_id != company: raise ValidationError( _('The Internal Project of a company should be in that company.' ))
def _check_leave_type_validity(self): for allocation in self: if allocation.holiday_status_id.validity_stop: vstop = allocation.holiday_status_id.validity_stop today = fields.Date.today() if vstop < today: raise ValidationError(_('You can allocate %s only before %s') % (allocation.holiday_status_id.display_name, allocation.holiday_status_id.validity_stop))
def _check_wallet(self): self.flush() for line in self: if self.env['lunch.cashmove'].get_wallet_balance(line.user_id) < 0: raise ValidationError( _('Your wallet does not contain enough money to order that.' 'To add some money to your wallet, please contact your lunch manager.' ))
def _check_percent(self): for term_line in self: if term_line.value == 'percent' and ( term_line.value_amount < 0.0 or term_line.value_amount > 100.0): raise ValidationError( _('Percentages on the Payment Terms lines must be between 0 and 100.' ))