1# -*- coding: utf-8 -*- 2 3from odoo import api, models, fields, _ 4from odoo.exceptions import UserError 5 6class ResPartnerBank(models.Model): 7 _inherit = 'res.partner.bank' 8 9 def build_qr_code_url(self, amount, free_communication, structured_communication, currency, debtor_partner, qr_method=None, silent_errors=True): 10 """ Returns the QR-code report URL to pay to this account with the given parameters, 11 or None if no QR-code could be generated. 12 13 :param amount: The amount to be paid 14 :param free_communication: Free communication to add to the payment when generating one with the QR-code 15 :param structured_communication: Structured communication to add to the payment when generating one with the QR-code 16 :param currency: The currency in which amount is expressed 17 :param debtor_partner: The partner to which this QR-code is aimed (so the one who will have to pay) 18 :param qr_method: The QR generation method to be used to make the QR-code. If None, the first one giving a result will be used. 19 :param silent_errors: If true, forbids errors to be raised if some tested QR-code format can't be generated because of incorrect data. 20 """ 21 if not self: 22 return None 23 24 self.ensure_one() 25 26 if not currency: 27 raise UserError(_("Currency must always be provided in order to generate a QR-code")) 28 29 available_qr_methods = self.get_available_qr_methods_in_sequence() 30 candidate_methods = qr_method and [(qr_method, dict(available_qr_methods)[qr_method])] or available_qr_methods 31 for candidate_method, candidate_name in candidate_methods: 32 if self._eligible_for_qr_code(candidate_method, debtor_partner, currency): 33 error_message = self._check_for_qr_code_errors(candidate_method, amount, currency, debtor_partner, free_communication, structured_communication) 34 35 if not error_message: 36 return self._get_qr_code_url(candidate_method, amount, currency, debtor_partner, free_communication, structured_communication) 37 38 elif not silent_errors: 39 error_header = _("The following error prevented '%s' QR-code to be generated though it was detected as eligible: ", candidate_name) 40 raise UserError( error_header + error_message) 41 42 return None 43 44 def _get_qr_code_url(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication): 45 """ Hook for extension, to support the different QR generation methods. 46 This function uses the provided qr_method to try generation a QR-code for 47 the given data. It it succeeds, it returns the report URL to make this 48 QR-code; else None. 49 50 :param qr_method: The QR generation method to be used to make the QR-code. 51 :param amount: The amount to be paid 52 :param currency: The currency in which amount is expressed 53 :param debtor_partner: The partner to which this QR-code is aimed (so the one who will have to pay) 54 :param free_communication: Free communication to add to the payment when generating one with the QR-code 55 :param structured_communication: Structured communication to add to the payment when generating one with the QR-code 56 """ 57 return None 58 59 @api.model 60 def _get_available_qr_methods(self): 61 """ Returns the QR-code generation methods that are available on this db, 62 in the form of a list of (code, name, sequence) elements, where 63 'code' is a unique string identifier, 'name' the name to display 64 to the user to designate the method, and 'sequence' is a positive integer 65 indicating the order in which those mehtods need to be checked, to avoid 66 shadowing between them (lower sequence means more prioritary). 67 """ 68 return [] 69 70 @api.model 71 def get_available_qr_methods_in_sequence(self): 72 """ Same as _get_available_qr_methods but without returning the sequence, 73 and using it directly to order the returned list. 74 """ 75 all_available = self._get_available_qr_methods() 76 all_available.sort(key=lambda x: x[2]) 77 return [(code, name) for (code, name, sequence) in all_available] 78 79 80 def _eligible_for_qr_code(self, qr_method, debtor_partner, currency): 81 """ Tells whether or not the criteria to apply QR-generation 82 method qr_method are met for a payment on this account, in the 83 given currency, by debtor_partner. This does not impeach generation errors, 84 it only checks that this type of QR-code *should be* possible to generate. 85 Consistency of the required field needs then to be checked by _check_for_qr_code_errors(). 86 """ 87 return False 88 89 def _check_for_qr_code_errors(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication): 90 """ Checks the data before generating a QR-code for the specified qr_method 91 (this method must have been checked for eligbility by _eligible_for_qr_code() first). 92 93 Returns None if no error was found, or a string describing the first error encountered 94 so that it can be reported to the user. 95 """ 96 return None