def _do_payment(self): if self.payment_token_id.acquirer_id.capture_manually: raise ValidationError( _('This feature is not available for payment acquirers set to the "Authorize" mode.\n' 'Please use a token from another provider than %s.') % self.payment_token_id.acquirer_id.name) reference = "P-%s-%s" % ( self.id, datetime.datetime.now().strftime('%y%m%d_%H%M%S')) tx = self.env['payment.transaction'].create({ 'amount': self.amount, 'acquirer_id': self.payment_token_id.acquirer_id.id, 'type': 'server2server', 'currency_id': self.currency_id.id, 'reference': reference, 'payment_token_id': self.payment_token_id.id, 'partner_id': self.partner_id.id, 'partner_country_id': self.partner_id.country_id.id, }) s2s_result = tx.s2s_do_transaction() if not s2s_result or tx.state != 'done': raise ValidationError( _("Payment transaction failed (%s)") % tx.state_message) self.payment_transaction_id = tx
def validate_iban(iban): iban = normalize_iban(iban) if not iban: raise ValidationError(_("No IBAN !")) 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_complete_move(self, move, theorical_lines): for aml in move.line_ids: line = (aml.name, round(aml.debit, 2), round(aml.credit, 2)) if line in theorical_lines: theorical_lines.remove(line) else: raise ValidationError('Unexpected journal item. (label: %s, debit: %s, credit: %s)' % (aml.name, round(aml.debit, 2), round(aml.credit, 2))) if theorical_lines: raise ValidationError('Remaining theorical line (not found). %s)' % ([(aml[0], aml[1], aml[2]) for aml in theorical_lines])) return True
def _check_pattern(self): p = self.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 ") + self.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 ") + self.pattern + _(": empty braces.")) elif len(findall) != 0: raise ValidationError(_("There is a syntax error in the barcode pattern ") + self.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_product_recursion(self): for bom in self: if bom.bom_line_ids.filtered(lambda x: x.product_id.product_tmpl_id == bom.product_tmpl_id): raise ValidationError( _('BoM line product %s should not be same as BoM product.') % bom.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( _('For the leaves to generate timesheet, the internal project and task are requried.' ))
def _check_communication(self, payment_method_id, communication): super(AccountPayment, self)._check_communication(payment_method_id, communication) if payment_method_id == self.env.ref('account_check_printing.account_payment_method_check').id: if not communication: return if len(communication) > 60: raise ValidationError(_("A check memo cannot exceed 60 characters."))
def action_capture(self): if any(self.mapped(lambda tx: tx.state != 'authorized')): raise ValidationError( _('Only transactions in the Authorized status can be captured.' )) for tx in self: tx.s2s_capture_transaction()
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_company_payment(self): if self.env['account.journal'].search_count([ ('id', 'in', self.journal_ids.ids), ('company_id', '!=', self.company_id.id) ]): raise ValidationError( _("The company of a payment method is different than the one of point of sale" ))
def _set_check_next_number(self): if self.check_next_number < self.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.") % self.check_sequence_id.number_next_actual) if self.check_sequence_id: self.check_sequence_id.sudo( ).number_next_actual = self.check_next_number
def _check_unicity(self): # open if there is no session in 'opening_control', 'opened', 'closing_control' for one user if self.search_count([('state', 'not in', ('closed', 'closing_control')), ('user_id', '=', self.user_id.id), ('rescue', '=', False)]) > 1: raise ValidationError( _("You cannot create two active sessions with the same responsible!" ))
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_date(self): """ Prevents the user to create an order in the past """ date_order = datetime.datetime.strptime(self.date, '%Y-%m-%d') date_today = datetime.datetime.strptime( fields.Date.context_today(self), '%Y-%m-%d') if (date_order < date_today): raise ValidationError(_('The date of your order is in the past.'))
def _check_main_currency_rounding(self): if any(precision.name == 'Account' and tools.float_compare( self.env.user.company_id.currency_id.rounding, 10**-precision.digits, precision_digits=6) == -1 for precision in self): raise ValidationError( _("You cannot define the decimal precision of 'Account' as greater than the rounding factor of the company's main currency" )) return True
def check_quantity(self): for quant in self: if float_compare( quant.quantity, 1, precision_rounding=quant.product_uom_id.rounding ) > 0 and quant.lot_id and quant.product_id.tracking == 'serial': raise ValidationError( _('A serial number should only be linked to a single product.' ))
def _validate_fiscalyear_lock(self, values): if values.get('fiscalyear_lock_date'): nb_draft_entries = self.env['account.move'].search([ ('company_id', 'in', [c.id for c in self]), ('state', '=', 'draft'), ('date', '<=', values['fiscalyear_lock_date']) ]) if nb_draft_entries: raise ValidationError( _('There are still unposted entries in the period you want to lock. You should either post or delete them.' ))
def _check_account_ids(self, vals): # Raise an error to prevent the account.budget.post to have not specified account_ids. # This check is done on create because require=True doesn't work on Many2many fields. if 'account_ids' in vals: account_ids = self.resolve_2many_commands('account_ids', vals['account_ids']) else: account_ids = self.account_ids if not account_ids: raise ValidationError( _('The budget must have at least one account.'))
def _check_attribute_value_ids(self): for product in self: attributes = self.env['product.attribute'] for value in product.attribute_value_ids: if value.attribute_id in attributes: raise ValidationError( _('Error! It is not allowed to choose more than one value for a given attribute.' )) if value.attribute_id.create_variant: attributes |= value.attribute_id return True
def _check_holidays(self): for holiday in self: if holiday.holiday_type != 'employee' or holiday.type != 'remove' or not holiday.employee_id or holiday.holiday_status_id.limit: continue leave_days = holiday.holiday_status_id.get_days( holiday.employee_id.id)[holiday.holiday_status_id.id] if float_compare(leave_days['remaining_leaves'], 0, precision_digits=2) == -1 or \ float_compare(leave_days['virtual_remaining_leaves'], 0, precision_digits=2) == -1: raise ValidationError( _('The number of remaining leaves is not sufficient for this leave type.\n' 'Please verify also the leaves waiting for validation.'))
def post(self): """ Create the journal items for the payment and update the payment's state to 'posted'. A journal entry is created containing an item in the source liquidity account (selected journal's default_debit or default_credit) and another in the destination reconciliable account (see _compute_destination_account_id). If invoice_ids is not empty, there will be one reconciliable move line per invoice to reconcile with. If the payment is a transfer, a second journal entry is created in the destination journal to receive money from the transfer account. """ for rec in self: if rec.state != 'draft': raise UserError(_("Only a draft payment can be posted.")) if any(inv.state != 'open' for inv in rec.invoice_ids): raise ValidationError( _("The payment cannot be processed because the invoice is not open!" )) # Use the right sequence to set the name if rec.payment_type == 'transfer': sequence_code = 'account.payment.transfer' else: if rec.partner_type == 'customer': if rec.payment_type == 'inbound': sequence_code = 'account.payment.customer.invoice' if rec.payment_type == 'outbound': sequence_code = 'account.payment.customer.refund' if rec.partner_type == 'supplier': if rec.payment_type == 'inbound': sequence_code = 'account.payment.supplier.refund' if rec.payment_type == 'outbound': sequence_code = 'account.payment.supplier.invoice' rec.name = self.env['ir.sequence'].with_context( ir_sequence_date=rec.payment_date).next_by_code(sequence_code) if not rec.name and rec.payment_type != 'transfer': raise UserError( _("You have to define a sequence for %s in your company.") % (sequence_code, )) # Create the journal entry amount = rec.amount * (rec.payment_type in ('outbound', 'transfer') and 1 or -1) move = rec._create_payment_entry(amount) # In case of a transfer, the first journal entry created debited the source liquidity account and credited # the transfer account. Now we debit the transfer account and credit the destination liquidity account. if rec.payment_type == 'transfer': transfer_credit_aml = move.line_ids.filtered( lambda r: r.account_id == rec.company_id. transfer_account_id) transfer_debit_aml = rec._create_transfer_entry(amount) (transfer_credit_aml + transfer_debit_aml).reconcile() rec.write({'state': 'posted', 'move_name': move.name}) return True
def _check_date(self): for holiday in self: domain = [ ('date_from', '<=', holiday.date_to), ('date_to', '>=', holiday.date_from), ('employee_id', '=', holiday.employee_id.id), ('id', '!=', holiday.id), ('type', '=', holiday.type), ('state', 'not in', ['cancel', 'refuse']), ] nholidays = self.search_count(domain) if nholidays: raise ValidationError( _('You can not have 2 leaves that overlaps on same day!'))
def _check_required_if_provider(self): """ If the field has 'required_if_provider="<provider>"' attribute, then it required if record.provider is <provider>. """ empty_field = [] for acquirer in self: for k, f in acquirer._fields.items(): if getattr(f, 'required_if_provider', None) == acquirer.provider and not acquirer[k]: empty_field.append(self.env['ir.model.fields'].search([ ('name', '=', k), ('model', '=', acquirer._name) ]).field_description) if empty_field: raise ValidationError((', ').join(empty_field)) return True
def action_mark_as_paid(self): """ Mark directly a sales order as paid if: - State: Quotation Sent, or sales order - Provider: wire transfer or manual config The transaction is marked as done The invoice may be generated and marked as paid if configured in the website settings """ self.ensure_one() if self.can_directly_mark_as_paid: self.action_confirm() if self.env['ir.config_parameter'].sudo().get_param('website_sale.automatic_invoice', default=False): self.payment_tx_id._generate_and_pay_invoice() self.payment_tx_id.state = 'done' else: raise ValidationError(_("The quote should be sent and the payment acquirer type should be manual or wire transfer"))
def _check_currencies(self): if self.pricelist_id not in self.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.journal_ids.mapped( lambda journal: journal.currency_id and journal.currency_id != self.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 isr_print(self): """ Triggered by the 'Print ISR' button. """ self.ensure_one() if self.l10n_ch_isr_valid: self.l10n_ch_isr_sent = True return self.env.ref('l10n_ch.l10n_ch_isr_report').report_action( self) else: raise ValidationError( _("""You cannot generate an ISR yet.\n For this, you need to :\n - set a valid postal account number (or an IBAN referencing one) for your company\n - define its bank\n - associate this bank with a postal reference for the currency used in this invoice\n - fill the 'bank account' field of the invoice with the postal to be used to receive the related payment. A default account will be automatically set for all invoices created after you defined a postal account for your company.""" ))
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.user.company_id 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_amount(self): if self.amount < 0: raise ValidationError(_('The payment amount cannot be negative.'))
def _check_seats_limit(self): if self.event_id.seats_availability == 'limited' and self.event_id.seats_max and self.event_id.seats_available < (1 if self.state == 'draft' else 0): raise ValidationError(_('No more seats available for this event.'))
def _check_closing_date(self): if self.date_end < self.date_begin: raise ValidationError(_('Closing Date cannot be set before Beginning Date.'))