def _setup_inv_data(self, journal, invoicer, contracts):
        """ Inherit to add BVR ref and mandate """
        inv_data = super()._setup_inv_data(journal, invoicer, contracts)

        ref = ""
        bank_modes = (
            self.env["account.payment.mode"]
                .with_context(lang="en_US")
                .search(["|", ("name", "like", "LSV"), ("name", "like", "Postfinance")])
        )
        bank = self.env["res.partner.bank"]
        if self.bvr_reference:
            ref = self.bvr_reference
            bank = bank.search([("acc_number", "=", "01444437")])
        elif self.payment_mode_id in bank_modes:
            seq = self.env["ir.sequence"]
            ref = mod10r(seq.next_by_code("contract.bvr.ref"))
            bank = self.payment_mode_id.fixed_journal_id.bank_account_id
        mandate = self.env["account.banking.mandate"].search(
            [("partner_id", "=", self.partner_id.id), ("state", "=", "valid")], limit=1
        )
        inv_data.update(
            {"reference": ref, "mandate_id": mandate.id, "partner_bank_id": bank.id, }
        )

        return inv_data
    def action_date_assign(self):
        """Method called when invoice is validated.
            - Add BVR Reference if payment mode is LSV and no reference is
              set.
            - Prevent validating invoices missing related contract.
        """
        to_validate = self.filtered(lambda i: i.partner_id.state != 'active')
        if to_validate:
            raise UserError(
                _('Please verify the partner before validating the invoice.'))

        for invoice in self.filtered('payment_mode_id'):
            if 'LSV' in invoice.payment_mode_id.name \
                    and not invoice.reference:
                seq = self.env['ir.sequence']
                ref = mod10r(seq.next_by_code('contract.bvr.ref'))
                invoice.write({'reference': ref})
            for invl in invoice.invoice_line_ids:
                if not invl.contract_id and invl.product_id.categ_name in (
                        SPONSORSHIP_CATEGORY, GIFT_CATEGORY):
                    raise UserError(
                        _("Invoice %s for '%s' is missing a sponsorship.") %
                        (str(invoice.id), invoice.partner_id.name))

        return super(AccountInvoice, self).action_date_assign()
    def generate_bvr_reference(self, contract, product):
        product = product.with_context(lang="en_US")
        ref = contract.gift_partner_id.ref
        bvr_reference = "0" * (9 + (7 - len(ref))) + ref
        commitment_number = str(contract.commitment_number)
        bvr_reference += "0" * (5 - len(commitment_number)) + commitment_number
        # Type of gift
        bvr_reference += str(GIFT_REF.index(product.default_code) + 1)
        bvr_reference += "0" * 4

        if contract.payment_mode_id and "LSV" in contract.payment_mode_id.name:
            # Get company BVR adherent number
            user = self.env.user
            bank_obj = self.env["res.partner.bank"]
            company_bank = bank_obj.search(
                [
                    ("partner_id", "=", user.company_id.partner_id.id),
                    ("l10n_ch_isr_subscription_chf", "!=", False),
                    ("acc_type", "=", "iban"),
                ],
                limit=1,
            )
            if company_bank:
                bvr_reference = company_bank.l10n_ch_isrb_id_number + bvr_reference[
                    9:]
        if len(bvr_reference) == 26:
            return mod10r(bvr_reference)

        return False
    def generate_bvr_reference(self, contract, product):
        product = product.with_context(lang='en_US')
        ref = getattr(contract, contract.send_gifts_to,
                      contract.correspondant_id).ref
        bvr_reference = '0' * (9 + (7 - len(ref))) + ref
        commitment_number = str(contract.commitment_number)
        bvr_reference += '0' * (5 - len(commitment_number)) + commitment_number
        # Type of gift
        bvr_reference += str(GIFT_NAMES.index(product.name) + 1)
        bvr_reference += '0' * 4

        if contract.payment_mode_id and 'LSV' in contract.payment_mode_id.name:
            # Get company BVR adherent number
            user = self.env.user
            bank_obj = self.env['res.partner.bank']
            company_bank = bank_obj.search([('partner_id', '=',
                                             user.company_id.partner_id.id),
                                            ('bvr_adherent_num', '!=', False)])
            if company_bank:
                bvr_reference = company_bank.bvr_adherent_num +\
                    bvr_reference[9:]
        if len(bvr_reference) == 26:
            return mod10r(bvr_reference)

        return False
    def _setup_inv_data(self, journal, invoicer, contracts):
        """ Inherit to add BVR ref and mandate """
        inv_data = super(ContractGroup, self)._setup_inv_data(
            journal, invoicer, contracts)

        ref = ''
        bank_modes = self.env['account.payment.mode'].with_context(
            lang='en_US').search(
            ['|', ('name', 'like', 'LSV'), ('name', 'like', 'Postfinance')])
        bank = self.env['res.partner.bank']
        if self.bvr_reference:
            ref = self.bvr_reference
            bank = bank.search([('acc_number', '=', '01444437')])
        elif self.payment_mode_id in bank_modes:
            seq = self.env['ir.sequence']
            ref = mod10r(seq.next_by_code('contract.bvr.ref'))
            bank = self.payment_mode_id.fixed_journal_id.bank_account_id
        mandate = self.env['account.banking.mandate'].search([
            ('partner_id', '=', self.partner_id.id),
            ('state', '=', 'valid')
        ], limit=1)
        inv_data.update({
            'reference': ref,
            'mandate_id': mandate.id,
            'partner_bank_id': bank.id,
        })

        return inv_data
    def _create_invoice_from_mv_lines(self, mv_line_dicts, invoice=None):
        # Generate a unique bvr_reference
        if self.ref and len(self.ref) == 27:
            ref = self.ref
        elif self.ref and len(self.ref) > 27:
            ref = mod10r(self.ref[:26])
        else:
            ref = mod10r((self.date.replace('-', '') + str(
                self.statement_id.id) + str(self.id)).ljust(26, '0'))

        if invoice:
            invoice.action_invoice_cancel()
            invoice.action_invoice_draft()
            invoice.env.invalidate_all()
            invoice.write({'origin': self.statement_id.name})

        else:
            # Lookup for an existing open invoice matching the criterias
            invoices = self._find_open_invoice(mv_line_dicts)
            if invoices:
                # Get the bvr reference of the invoice or set it
                invoice = invoices[0]
                invoice.write({'origin': self.statement_id.name})
                if invoice.reference and not self.ref:
                    ref = invoice.reference
                else:
                    invoice.write({'reference': ref})
                self.write({
                    'ref': ref,
                    'invoice_id': invoice.id})
                return True

            # Setup a new invoice if no existing invoice is found
            inv_data = self._get_invoice_data(ref, mv_line_dicts)
            invoice = self.env['account.invoice'].create(inv_data)

        for mv_line_dict in mv_line_dicts:
            inv_line_data = self._get_invoice_line_data(mv_line_dict, invoice)
            self.env['account.invoice.line'].create(inv_line_data)

        invoice.action_invoice_open()
        self.ref = ref

        # Update move_lines data
        counterpart = invoice.move_id.line_ids.filtered(
            lambda ml: ml.debit > 0)
        return counterpart
Example #7
0
    def _create_invoice_from_mv_lines(self, mv_line_dicts, invoice=None):
        # Generate a unique bvr_reference
        if self.ref and len(self.ref) == 27:
            ref = self.ref
        elif self.ref and len(self.ref) > 27:
            ref = mod10r(self.ref[:26])
        else:
            ref = mod10r(
                str(self.date).replace("-", "") + str(self.statement_id.id) +
                str(self.id)).ljust(26, "0")

        if invoice:
            invoice.action_invoice_cancel()
            invoice.action_invoice_draft()
            invoice.env.clear()
            invoice.write({"origin": self.statement_id.name})

        else:
            # Lookup for an existing open invoice matching the criterias
            invoices = self._find_open_invoice(mv_line_dicts)
            if invoices:
                # Get the bvr reference of the invoice or set it
                invoice = invoices[0]
                invoice.write({"origin": self.statement_id.name})
                if invoice.reference and not self.ref:
                    ref = invoice.reference
                else:
                    invoice.write({"reference": ref})
                self.write({"ref": ref, "invoice_id": invoice.id})
                return True

            # Setup a new invoice if no existing invoice is found
            inv_data = self._get_invoice_data(ref, mv_line_dicts)
            invoice = self.env["account.invoice"].create(inv_data)

        for mv_line_dict in mv_line_dicts:
            inv_line_data = self._get_invoice_line_data(mv_line_dict, invoice)
            self.env["account.invoice.line"].create(inv_line_data)

        invoice.action_invoice_open()
        self.ref = ref

        # Update move_lines data
        counterpart = invoice.move_id.line_ids.filtered(
            lambda ml: ml.debit > 0)
        return counterpart
    def on_change_bvr_ref(self):
        """ Test the validity of a reference number. """
        bvr_reference = self.bvr_reference
        is_valid = bvr_reference and bvr_reference.isdigit()
        if is_valid and len(bvr_reference) == 26:
            bvr_reference = mod10r(bvr_reference)
        elif is_valid and len(bvr_reference) == 27:
            valid_ref = mod10r(bvr_reference[:-1])
            is_valid = (valid_ref == bvr_reference)
        else:
            is_valid = False

        if is_valid:
            self.bvr_reference = bvr_reference
        elif bvr_reference:
            raise UserError(
                _('The reference of the partner has not been set, or is in '
                  'wrong format. Please make sure to enter a valid BVR '
                  'reference for the contract.'))
Example #9
0
 def _is_isr_reference(self):
     """
     Function to validate a ISR reference like :
     0100054150009>132000000000000000000000014+ 1300132412>
     The validation is based on l10n_ch
     """
     if not self.reference:
         raise exceptions.ValidationError(_('ISR Reference is required'))
     # In this case
     # <010001000060190> 052550152684006+ 43435>
     # the reference 052550152684006 do not match modulo 10
     #
     if (mod10r(self.reference[:-1]) != self.reference
             and len(self.reference) == 15):
         return True
     #
     if mod10r(self.reference[:-1]) != self.reference:
         raise exceptions.ValidationError(
             _('Invalid ISR Number (wrong checksum).'))
Example #10
0
def is_bvr_ref(ref):
    if not ref:
        return False  # Empty is not valid
    clean_ref = ref.replace(' ', '')
    if not clean_ref.isdigit() or len(clean_ref) > 27:
        return False
    clean_ref = clean_ref.rjust(27, '0')  # Add zeros to the left
    if not clean_ref == mod10r(clean_ref[0:26]):
        return False

    return True
Example #11
0
    def validate_global_context_dict(self):
        """Validate BVR record values"""
        super(RecordGt826, self).validate_global_context_dict()
        if not self.global_values['reference']:
            raise exceptions.UserError(
                _('You must provide a BVR reference'
                  'number \n for the line: %s') % self.pline.name
            )
        ref = self.global_values['reference'].replace(' ', '')
        self.global_values['reference'] = ref
        if self.is_9_pos_adherent:
            if len(ref) > 27:
                raise exceptions.UserError(
                    _('BVR reference number is not valid \n'
                      'for the line: %s. \n'
                      'Reference is too long.') % self.pline.name
                )
            # do a mod10 check
            if mod10r(ref[:-1]) != ref:
                raise exceptions.UserError(
                    _('BVR reference number is not valid \n'
                      'for the line: %s. \n'
                      'Mod10 check failed') % self.pline.name
                )
            # fill reference with 0
            self.global_values['reference'] = ref.rjust(27, '0')
        else:
            # reference of BVR adherent with 5 positions number
            # have 15 positions references
            if len(ref) > 15:
                raise exceptions.UserError(
                    _('BVR reference number is not valid \n'
                      'for the line: %s. \n Reference is too long '
                      'for this type of beneficiary.') % self.pline.name
                )
            # complete 15 first digit with 0 on left and complete 27 digits
            # with trailing spaces
            # exemple: 123456 becomes 00000000012345____________
            adjust = ref.rjust(15, '0').ljust(27, ' ')
            self.global_values['reference'] = adjust

        if not self.global_values['partner_bvr']:
            raise exceptions.UserError(
                _('You must provide a BVR number\n'
                  'for the bank account: %s'
                  'on line: %s') % (
                    self.pline.partner_bank_id.get_account_number(),
                    self.pline.name)
            )
 def _update_invoice_lines(self, invoices):
     """ Update bvr_reference of invoices """
     super(RecurringContracts, self)._update_invoice_lines(invoices)
     for contract in self:
         ref = False
         bank_modes = self.env['account.payment.mode'].with_context(
             lang='en_US').search(
             ['|', ('name', 'like', 'LSV'),
              ('name', 'like', 'Postfinance')])
         if contract.group_id.bvr_reference:
             ref = contract.group_id.bvr_reference
         elif contract.payment_mode_id in bank_modes:
             seq = self.env['ir.sequence']
             ref = mod10r(seq.next_by_code('contract.bvr.ref'))
         invoices.write({'reference': ref})
Example #13
0
    def _is_isr_reference(self):
        """Check if the communication is a valid ISR reference

        e.g.
        210000000003139471430009017
        21 00000 00003 13947 14300 09017

        This is used to determine SEPA local instrument

        """
        if not self.reference:
            return False
        if re.match(r'^(\d{27}|\d{2}( \d{5}){5})$', self.reference):
            ref = self.reference.replace(' ', '')
            return ref == mod10r(ref[:-1])
        return False
Example #14
0
 def _update_invoice_lines(self, invoices):
     """ Update bvr_reference of invoices """
     super(RecurringContracts, self)._update_invoice_lines(invoices)
     for contract in self:
         ref = False
         bank_modes = self.env['account.payment.mode'].with_context(
             lang='en_US').search([
                 '|', ('name', 'like', 'LSV'),
                 ('name', 'like', 'Postfinance')
             ])
         if contract.group_id.bvr_reference:
             ref = contract.group_id.bvr_reference
         elif contract.payment_mode_id in bank_modes:
             seq = self.env['ir.sequence']
             ref = mod10r(seq.next_by_code('contract.bvr.ref'))
         invoices.write({'reference': ref})
Example #15
0
 def _update_invoice_lines(self, invoices):
     """ Update bvr_reference of invoices """
     success = super()._update_invoice_lines(invoices)
     for contract in self:
         ref = False
         bank_modes = (self.env["account.payment.mode"].with_context(
             lang="en_US").search([
                 "|", ("name", "like", "LSV"),
                 ("name", "like", "Postfinance")
             ]))
         if contract.group_id.bvr_reference:
             ref = contract.group_id.bvr_reference
         elif contract.payment_mode_id in bank_modes:
             seq = self.env["ir.sequence"]
             ref = mod10r(seq.next_by_code("contract.bvr.ref"))
         invoices.write({"reference": ref})
     return success
Example #16
0
    def is_post_dd_ident_valid(self, dd_identifier):
        """ Check if given Postfinance DD Identifier is valid """
        if not isinstance(dd_identifier, basestring):
            return False
        try:
            dd_identifier.decode('ascii')
        except UnicodeDecodeError:
            raise exceptions.ValidationError(
                _('DD identifier should contain only ASCII caracters.')
            )

        if not len(dd_identifier) == 6:
            return False

        if not dd_identifier == mod10r(dd_identifier[:5]):
            return False

        return True
Example #17
0
 def generate_bvr_reference(self, product):
     """
     Generates a bvr reference for a donation to the fund given by
     the product.
     :param product: fund product with a fund_id
     :return: bvr reference for the partner
     """
     self.ensure_one()
     if isinstance(product, int):
         product = self.env['product.product'].browse(product)
     ref = self.ref
     bvr_reference = '0' * (9 + (7 - len(ref))) + ref
     bvr_reference += '0' * 5
     bvr_reference += '6'  # Fund donation
     bvr_reference += '0' * (4 - len(product.fund_id)) + product.fund_id
     bvr_reference += '0' * 4
     if len(bvr_reference) == 26:
         return mod10r(bvr_reference)
Example #18
0
 def _check_9_pos_postal_num(self, number):
     """
     Predicate that checks if a postal number
     is in format xx-xxxxxx-x is correct,
     return true if it matches the pattern
     and if check sum mod10 is ok
     :param number: postal number to validate
     :returns: True if is it a 9 len postal account
     :rtype: bool
     """
     pattern = r'^[0-9]{2}-[0-9]{1,6}-[0-9]$'
     if not re.search(pattern, number):
         return False
     nums = number.split('-')
     prefix = nums[0]
     num = nums[1].rjust(6, '0')
     checksum = nums[2]
     expected_checksum = mod10r(prefix + num)[-1]
     return expected_checksum == checksum
    def action_date_assign(self):
        """Method called when invoice is validated.
            - Add BVR Reference if payment mode is LSV and no reference is
              set.
            - Prevent validating invoices missing related contract.
        """
        for invoice in self.filtered('payment_mode_id'):
            if 'LSV' in invoice.payment_mode_id.name \
                    and not invoice.reference:
                seq = self.env['ir.sequence']
                ref = mod10r(seq.next_by_code('contract.bvr.ref'))
                invoice.write({'reference': ref})
            for invl in invoice.invoice_line_ids:
                if not invl.contract_id and invl.product_id.categ_name in (
                        SPONSORSHIP_CATEGORY, GIFT_CATEGORY):
                    raise UserError(
                        _("Invoice %s for '%s' is missing a sponsorship.") %
                        (str(invoice.id), invoice.partner_id.name))

        return super(AccountInvoice, self).action_date_assign()
    def generate_bvr_reference(self, partner):
        """
        Generates a BVR reference for the product.
        :param partner:
        :return: string: the BVR reference
        """
        self.ensure_one()
        ref = partner.ref
        bvr_reference = '0' * (9 + (7 - len(ref))) + ref
        commitment_number = '0'
        bvr_reference += '0' * (5 - len(commitment_number)) + commitment_number
        # Type for Funds => 6
        bvr_reference += '6'
        # Fund id
        fund_id = str(self.fund_id)
        bvr_reference += '0' * (4 - len(fund_id)) + fund_id

        if len(bvr_reference) == 26:
            return self.env['l10n_ch.payment_slip']._space(mod10r(
                bvr_reference).lstrip('0'))
Example #21
0
def validate_l10n_ch_postal(postal_acc_number):
    """Check if the string postal_acc_number is a valid postal account number,
    i.e. it only contains ciphers and is last cipher is the result of a
    recursive modulo 10 operation ran over the rest of it. Shorten form with -
    is also accepted.
    Raise a ValidationError if check fails
    """
    if not postal_acc_number:
        raise ValidationError(_("There is no postal account number."))
    if re.match('^[0-9]{2}-[0-9]{1,6}-[0-9]$', postal_acc_number):
        ref_subparts = postal_acc_number.split('-')
        postal_acc_number = (ref_subparts[0] + ref_subparts[1].rjust(6, '0') +
                             ref_subparts[2])

    if not re.match(r'\d{9}$', postal_acc_number or ''):
        msg = _("The postal does not match 9 digits position.")
        raise ValidationError(msg)

    acc_number_without_check = postal_acc_number[:-1]
    if not mod10r(acc_number_without_check) == postal_acc_number:
        raise ValidationError(_("The postal account number is not valid."))
    def action_date_assign(self):
        """Method called when invoice is validated.
            - Add BVR Reference if payment mode is LSV and no reference is
              set.
            - Prevent validating invoices missing related contract.
        """
        for invoice in self.filtered("payment_mode_id"):
            if "LSV" in invoice.payment_mode_id.name and not invoice.reference:
                seq = self.env["ir.sequence"]
                ref = mod10r(seq.next_by_code("contract.bvr.ref"))
                invoice.write({"reference": ref})
            for invl in invoice.invoice_line_ids:
                if not invl.contract_id and invl.product_id.categ_name in (
                        SPONSORSHIP_CATEGORY,
                        GIFT_CATEGORY,
                ):
                    raise UserError(
                        _("Invoice %s for '%s' is missing a sponsorship.") %
                        (str(invoice.id), invoice.partner_id.name))

        return super().action_date_assign()
    def compute_partner_bvr_ref(self, partner=None, is_lsv=False):
        """ Generates a new BVR Reference.
        See file /nas/it/devel/Code_ref_BVR.xls for more information."""
        self.ensure_one()
        if self.exists():
            # If group was already existing, retrieve any existing reference
            ref = self.bvr_reference
            if ref:
                return ref
        partner = partner or self.partner_id
        result = "0" * (9 + (7 - len(partner.ref))) + partner.ref
        count_groups = str(self.search_count([("partner_id", "=", partner.id)]))
        result += "0" * (5 - len(count_groups)) + count_groups
        # Type '0' = Sponsorship
        result += "0"
        result += "0" * 4

        if is_lsv:
            result = "004874969" + result[9:]
        if len(result) == 26:
            return mod10r(result)
Example #24
0
 def get_scan_line(self, account, reference, amount=False):
     """ Generate a scan line given the reference """
     if amount:
         line = "01"
         decimal_amount, int_amount = math.modf(amount)
         str_amount = (str(int(int_amount)) +
                       str(int(decimal_amount * 100)).rjust(2, '0')).rjust(
                           10, '0')
         line += str_amount
         line = mod10r(line)
     else:
         line = "042"
     line += ">"
     line += reference.replace(" ", "").rjust(27, '0')
     line += '+ '
     account_components = account.split('-')
     bank_identifier = "%s%s%s" % (account_components[0],
                                   account_components[1].rjust(
                                       6, '0'), account_components[2])
     line += bank_identifier
     line += '>'
     return line
 def get_scan_line(self, account, reference, amount=False):
     """ Generate a scan line given the reference """
     if amount:
         line = "01"
         decimal_amount, int_amount = math.modf(amount)
         str_amount = (str(int(int_amount)) +
                       str(int(decimal_amount * 100)).rjust(2, "0")).rjust(
                           10, "0")
         line += str_amount
         line = mod10r(line)
     else:
         line = "042"
     line += ">"
     line += reference.replace(" ", "").rjust(27, "0")
     line += "+ "
     account_components = account.split("-")
     bank_identifier = (f"{account_components[0]}"
                        f"{account_components[1].rjust(6, '0')}"
                        f"{account_components[2]}")
     line += bank_identifier
     line += ">"
     return line
    def compute_partner_bvr_ref(self, partner=None, is_lsv=False):
        """ Generates a new BVR Reference.
        See file /nas/it/devel/Code_ref_BVR.xls for more information."""
        self.ensure_one()
        if self.exists():
            # If group was already existing, retrieve any existing reference
            ref = self.bvr_reference
            if ref:
                return ref
        partner = partner or self.partner_id
        result = '0' * (9 + (7 - len(partner.ref))) + partner.ref
        count_groups = str(self.search_count(
            [('partner_id', '=', partner.id)]))
        result += '0' * (5 - len(count_groups)) + count_groups
        # Type '0' = Sponsorship
        result += '0'
        result += '0' * 4

        if is_lsv:
            result = '004874969' + result[9:]
        if len(result) == 26:
            return mod10r(result)
    def generate_bvr_reference(self, contract, product):
        product = product.with_context(lang='en_US')
        ref = contract.gift_partner_id.ref
        bvr_reference = '0' * (9 + (7 - len(ref))) + ref
        commitment_number = str(contract.commitment_number)
        bvr_reference += '0' * (5 - len(commitment_number)) + commitment_number
        # Type of gift
        bvr_reference += str(GIFT_NAMES.index(product.name) + 1)
        bvr_reference += '0' * 4

        if contract.payment_mode_id and 'LSV' in contract.payment_mode_id.name:
            # Get company BVR adherent number
            user = self.env.user
            bank_obj = self.env['res.partner.bank']
            company_bank = bank_obj.search([
                ('partner_id', '=', user.company_id.partner_id.id),
                ('bvr_adherent_num', '!=', False)])
            if company_bank:
                bvr_reference = company_bank.bvr_adherent_num +\
                    bvr_reference[9:]
        if len(bvr_reference) == 26:
            return mod10r(bvr_reference)

        return False
Example #28
0
    def _compute_l10n_ch_isr_number(self):
        r"""Generates the ISR or QRR reference

        An ISR references are 27 characters long.
        QRR is a recycling of ISR for QR-bills. Thus works the same.

        The invoice sequence number is used, removing each of its non-digit characters,
        and pad the unused spaces on the left of this number with zeros.
        The last digit is a checksum (mod10r).

        There are 2 types of references:

        * ISR (Postfinance)

            The reference is free but for the last
            digit which is a checksum.
            If shorter than 27 digits, it is filled with zeros on the left.

            e.g.

                120000000000234478943216899
                \________________________/|
                         1                2
                (1) 12000000000023447894321689 | reference
                (2) 9: control digit for identification number and reference

        * ISR-B (Indirect through a bank, requires a customer ID)

            In case of ISR-B The firsts digits (usually 6), contain the customer ID
            at the Bank of this ISR's issuer.
            The rest (usually 20 digits) is reserved for the reference plus the
            control digit.
            If the [customer ID] + [the reference] + [the control digit] is shorter
            than 27 digits, it is filled with zeros between the customer ID till
            the start of the reference.

            e.g.

                150001123456789012345678901
                \____/\__________________/|
                   1           2          3
                (1) 150001 | id number of the customer (size may vary)
                (2) 12345678901234567890 | reference
                (3) 1: control digit for identification number and reference
        """
        for record in self:

            if (record._need_isr_ref()) and record.number:
                id_number = record._get_isrb_id_number()
                if id_number:
                    id_number = id_number.zfill(l10n_ch_ISR_ID_NUM_LENGTH)
                invoice_ref = re.sub(r'[^\d]', '', record.number)
                # keep only the last digits if it exceed boundaries
                full_len = len(id_number) + len(invoice_ref)
                ref_payload_len = l10n_ch_ISR_NUMBER_LENGTH - 1
                extra = full_len - ref_payload_len
                if extra > 0:
                    invoice_ref = invoice_ref[extra:]
                internal_ref = invoice_ref.zfill(ref_payload_len -
                                                 len(id_number))
                record.l10n_ch_isr_number = mod10r(id_number + internal_ref)
            else:
                record.l10n_ch_isr_number = False