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 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_currencies(self): for config in self: if config.use_pricelist and config.pricelist_id not in config.available_pricelist_ids: raise ValidationError( _("The default pricelist must be included in the available pricelists." )) if any( self.available_pricelist_ids.mapped( lambda pricelist: pricelist.currency_id != self.currency_id )): raise ValidationError( _("All available pricelists must be in the same currency as the company or" " as the Sales Journal set on this point of sale if you use" " the Accounting application.")) if self.invoice_journal_id.currency_id and self.invoice_journal_id.currency_id != self.currency_id: raise ValidationError( _("The invoice journal must be in the same currency as the Sales Journal or the company currency if that is not set." )) if any( self.payment_method_ids\ .filtered(lambda pm: pm.is_cash_count)\ .mapped(lambda pm: self.currency_id not in (self.company_id.currency_id | pm.cash_journal_id.currency_id)) ): raise ValidationError( _("All payment methods must be in the same currency as the Sales Journal or the company currency if that is not set." ))
def _check_url_to(self): for rewrite in self: if rewrite.redirect_type == '308': if not rewrite.url_to: raise ValidationError(_('"URL to" can not be empty.')) elif not rewrite.url_to.startswith('/'): raise ValidationError( _('"URL to" must start with a leading slash.'))
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 _onchange_amount(self): if float_compare(self.amount_max, self.amount, precision_rounding=self.currency_id.rounding or 0.01) == -1: raise ValidationError( _("Please set an amount smaller than %s.") % (self.amount_max)) if self.amount <= 0: raise ValidationError( _("The value of the payment amount must be positive."))
def _check_model(self): for action in self: if action.res_model not in self.env: raise ValidationError( _('Invalid model name %r in action definition.') % action.res_model) if action.binding_model_id and action.binding_model_id.model not in self.env: raise ValidationError( _('Invalid model name %r in action definition.') % action.binding_model_id.model)
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_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_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 _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_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_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_adyen_ask_customer_for_tip(self): for config in self: if config.adyen_ask_customer_for_tip and ( not config.tip_product_id or not config.iface_tipproduct): raise ValidationError( _("Please configure a tip product for POS %s to support tipping with Adyen." ) % config.name)
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 _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') and c.employee_id): 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 _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_companies(self): if any( self.available_pricelist_ids.mapped( lambda pl: pl.company_id.id not in (False, self.company_id.id))): raise ValidationError( _("The selected pricelists must belong to no company or the company of the point of sale." ))
def _check_only_one_good_answer(self): for question in self: good_answer_count = 0 for answer in question.answer_ids: if answer.is_correct: good_answer_count += 1 if good_answer_count > 1: raise ValidationError(_('Question "%s" can only have one good answer') % question.question)
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_company_payment(self): if self.env['pos.payment.method'].search_count([ ('id', 'in', self.payment_method_ids.ids), ('company_id', '!=', self.company_id.id) ]): raise ValidationError( _("The method payments and the point of sale must belong to the same company." ))
def _check_recursion(self): if any(item.base == 'pricelist' and item.pricelist_id and item.pricelist_id == item.base_pricelist_id for item in self): raise ValidationError( _('You cannot assign the Main Pricelist as Other Pricelist in PriceList Item' )) return True
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_session_state(self): open_session = self.env['pos.session'].search([ ('config_id', '=', self.id), ('state', '!=', 'closed') ]) if open_session: raise ValidationError( _("You are not allowed to change the cash control status while a session is already opened." ))
def check_reserved_done_quantity(self): for move_line in self: if move_line.state == 'done' and not float_is_zero( move_line.product_uom_qty, precision_digits=self.env['decimal.precision']. precision_get('Product Unit of Measure')): raise ValidationError( _('A done move line should never have a reserved quantity.' ))
def _check_valuation_accouts(self): # Prevent to set the valuation account as the input or output account. for category in self: valuation_account = category.property_stock_valuation_account_id input_and_output_accounts = category.property_stock_account_input_categ_id | category.property_stock_account_output_categ_id if valuation_account and valuation_account in input_and_output_accounts: raise ValidationError( _('The Stock Input and/or Output accounts cannot be the same than the Stock Valuation account.' ))