def _sdd_xml_gen_header(self, company_id, CstmrDrctDbtInitn):
     """ Generates the header of the SDD XML file.
     """
     GrpHdr = create_xml_node(CstmrDrctDbtInitn, 'GrpHdr')
     create_xml_node(GrpHdr, 'MsgId', str(time.time()))  # Using time makes sure the identifier is unique in an easy way
     create_xml_node(GrpHdr, 'CreDtTm', datetime.now().strftime('%Y-%m-%dT%H:%M:%S'))
     create_xml_node(GrpHdr, 'NbOfTxs', str(len(self)))
     create_xml_node(GrpHdr, 'CtrlSum', float_repr(sum(x.amount for x in self), precision_digits=2))  # This sum ignores the currency, it is used as a checksum (see SEPA rulebook)
     InitgPty = create_xml_node(GrpHdr, 'InitgPty')
     create_xml_node(InitgPty, 'Nm', company_id.name[:140])
     create_xml_node_chain(InitgPty, ['Id','OrgId','Othr','Id'], company_id.sdd_creditor_identifier)
Exemple #2
0
    def _get_PmtTpInf(self, sct_generic=False, local_instrument=None):
        PmtTpInf = etree.Element("PmtTpInf")

        if not sct_generic:
            SvcLvl = etree.SubElement(PmtTpInf, "SvcLvl")
            Cd = etree.SubElement(SvcLvl, "Cd")
            Cd.text = 'SEPA'

        if local_instrument:
            create_xml_node_chain(PmtTpInf, ['LclInstrm', 'Prtry'],
                                  local_instrument)

        return PmtTpInf
Exemple #3
0
    def _get_RmtInf(self, payment, local_instrument=None):
        if not payment['ref']:
            return False
        RmtInf = etree.Element("RmtInf")

        # In Switzerland, postal accounts and QR-IBAN accounts always require a structured communication with the ISR reference
        qr_iban = self._is_qr_iban(payment)
        if local_instrument == 'CH01' or qr_iban:
            ref = payment['ref'].replace(' ', '')
            ref = ref.rjust(27, '0')
            CdtrRefInf = create_xml_node_chain(RmtInf,
                                               ['Strd', 'CdtrRefInf'])[1]
            if qr_iban:
                create_xml_node_chain(CdtrRefInf, ['Tp', 'CdOrPrtry', 'Prtry'],
                                      "QRR")
            Ref = etree.SubElement(CdtrRefInf, "Ref")
            Ref.text = ref
        else:
            Ustrd = etree.SubElement(RmtInf, "Ustrd")
            Ustrd.text = sanitize_communication(payment['ref'])
        return RmtInf
Exemple #4
0
    def sdd_xml_gen_payment(self, company_id, partner, end2end_counter,
                            PmtInf):
        """ Appends to a SDD XML file being generated all the data related to the
        payments of a given partner.
        """
        #The two following conditions should never execute.
        #They are here to be sure future modifications won't ever break everything.
        if self.company_id != company_id:
            raise UserError(
                _("Trying to generate a Direct Debit XML file containing payments from another company than that file's creditor."
                  ))

        if self.payment_method_id.code != 'sdd':
            raise UserError(
                _("Trying to generate a Direct Debit XML for payments coming from another payment method than SEPA Direct Debit."
                  ))

        DrctDbtTxInf = create_xml_node_chain(
            PmtInf, ['DrctDbtTxInf', 'PmtId', 'EndToEndId'],
            str(end2end_counter))[0]

        InstdAmt = create_xml_node(DrctDbtTxInf, 'InstdAmt',
                                   float_repr(self.amount, precision_digits=2))
        InstdAmt.attrib['Ccy'] = self.currency_id.name

        MndtRltdInf = create_xml_node_chain(
            DrctDbtTxInf, ['DrctDbtTx', 'MndtRltdInf', 'MndtId'],
            self.sdd_mandate_id.name)[-2]
        create_xml_node(MndtRltdInf, 'DtOfSgntr',
                        self.sdd_mandate_id.start_date)
        create_xml_node_chain(DrctDbtTxInf, ['DbtrAgt', 'FinInstnId', 'BIC'],
                              self.sdd_mandate_id.partner_bank_id.bank_id.bic)
        Dbtr = create_xml_node_chain(DrctDbtTxInf, ['Dbtr', 'Nm'],
                                     partner.name)[0]

        if self.sdd_mandate_id.debtor_id_code:
            create_xml_node(Dbtr, 'Id', self.sdd_mandate_id.debtor_id_code)

        if partner.contact_address:
            PstlAdr = create_xml_node(Dbtr, 'PstlAdr')
            if partner.country_id and partner.country_id.code:
                create_xml_node(PstlAdr, 'Ctry', partner.country_id.code)
            n_line = 0
            contact_address = partner.contact_address.replace('\n',
                                                              ' ').strip()
            while contact_address and n_line < 2:
                create_xml_node(PstlAdr, 'AdrLine', contact_address[:70])
                contact_address = contact_address[70:]
                n_line = n_line + 1

        create_xml_node_chain(
            DrctDbtTxInf, ['DbtrAcct', 'Id', 'IBAN'],
            self.sdd_mandate_id.partner_bank_id.sanitized_acc_number)
Exemple #5
0
    def _sdd_xml_gen_payment_group(self, company_id, required_collection_date,
                                   payment_info_counter, journal,
                                   CstmrDrctDbtInitn):
        """ Generates a group of payments in the same PmtInfo node, provided
        that they share the same journal."""
        PmtInf = create_xml_node(CstmrDrctDbtInitn, 'PmtInf')
        create_xml_node(PmtInf, 'PmtInfId', str(payment_info_counter))
        create_xml_node(PmtInf, 'PmtMtd', 'DD')
        create_xml_node(
            PmtInf, 'BtchBookg',
            bool(self.env['ir.config_parameter'].sudo().get_param(
                'account_sepa_direct_debit_no_batch_booking')) and '0' or '1')
        create_xml_node(PmtInf, 'NbOfTxs', str(len(self)))
        create_xml_node(
            PmtInf, 'CtrlSum',
            float_repr(sum(x.amount for x in self), precision_digits=2)
        )  # This sum ignores the currency, it is used as a checksum (see SEPA rulebook)

        PmtTpInf = create_xml_node_chain(PmtInf, ['PmtTpInf', 'SvcLvl', 'Cd'],
                                         'SEPA')[0]
        create_xml_node_chain(PmtTpInf, ['LclInstrm', 'Cd'], 'CORE')
        create_xml_node(PmtTpInf, 'SeqTp', 'FRST')
        #Note: FRST refers to the COLLECTION of payments, not the type of mandate used
        #This value is only used for informatory purpose.

        create_xml_node(
            PmtInf, 'ReqdColltnDt',
            fields.Date.from_string(required_collection_date).strftime(
                "%Y-%m-%d"))
        create_xml_node_chain(
            PmtInf, ['Cdtr', 'Nm'], company_id.name[:70]
        )  # SEPA regulation gives a maximum size of 70 characters for this field
        create_xml_node_chain(PmtInf, ['CdtrAcct', 'Id', 'IBAN'],
                              journal.bank_account_id.sanitized_acc_number)
        create_xml_node_chain(PmtInf, ['CdtrAgt', 'FinInstnId', 'BIC'],
                              (journal.bank_id.bic or '').replace(' ',
                                                                  '').upper())

        CdtrSchmeId_Othr = create_xml_node_chain(
            PmtInf, ['CdtrSchmeId', 'Id', 'PrvtId', 'Othr', 'Id'],
            company_id.sdd_creditor_identifier)[-2]
        create_xml_node_chain(CdtrSchmeId_Othr, ['SchmeNm', 'Prtry'], 'SEPA')

        for payment in self:
            payment.sdd_xml_gen_payment(company_id, payment.partner_id,
                                        payment.name[:35], PmtInf)
Exemple #6
0
    def _sdd_xml_gen_partner(self, company_id, required_collection_date,
                             payment_info_counter, mandate, CstmrDrctDbtInitn):
        """ Appends to a SDD XML file being generated all the data related to a partner
        and his payments. self must be a recordset whose payments share the same partner.

        /!\ => Grouping the payments by mandate caused problems with Dutch banks, because
        of the too large number of distinct transactions in the file. We fixed that so that we now
        group on payment journal. This function is not used anymore
        and will be removed. It has been replaced by _sdd_xml_gen_payment_group.
        """
        PmtInf = create_xml_node(CstmrDrctDbtInitn, 'PmtInf')
        create_xml_node(PmtInf, 'PmtInfId', str(payment_info_counter))
        create_xml_node(PmtInf, 'PmtMtd', 'DD')
        create_xml_node(PmtInf, 'NbOfTxs', str(len(self)))
        create_xml_node(
            PmtInf, 'CtrlSum',
            float_repr(sum(x.amount for x in self), precision_digits=2)
        )  # This sum ignores the currency, it is used as a checksum (see SEPA rulebook)

        PmtTpInf = create_xml_node_chain(PmtInf, ['PmtTpInf', 'SvcLvl', 'Cd'],
                                         'SEPA')[0]
        create_xml_node_chain(PmtTpInf, ['LclInstrm', 'Cd'], 'CORE')
        create_xml_node(PmtTpInf, 'SeqTp', 'FRST')
        #Note: FRST refers to the COLLECTION of payments, not the type of mandate used
        #This value is only used for informatory purpose.

        create_xml_node(
            PmtInf, 'ReqdColltnDt',
            fields.Date.from_string(required_collection_date).strftime(
                "%Y-%m-%d"))
        create_xml_node_chain(
            PmtInf, ['Cdtr', 'Nm'], company_id.name[:70]
        )  # SEPA regulation gives a maximum size of 70 characters for this field
        create_xml_node_chain(
            PmtInf, ['CdtrAcct', 'Id', 'IBAN'],
            mandate.payment_journal_id.bank_account_id.sanitized_acc_number)
        create_xml_node_chain(PmtInf, ['CdtrAgt', 'FinInstnId', 'BIC'],
                              (mandate.payment_journal_id.bank_id.bic
                               or '').replace(' ', '').upper())

        CdtrSchmeId_Othr = create_xml_node_chain(
            PmtInf, ['CdtrSchmeId', 'Id', 'PrvtId', 'Othr', 'Id'],
            company_id.sdd_creditor_identifier)[-2]
        create_xml_node_chain(CdtrSchmeId_Othr, ['SchmeNm', 'Prtry'], 'SEPA')

        partner = None
        for partner_payment in self:
            if not partner:
                partner = partner_payment.partner_id
            elif partner != partner_payment.partner_id:
                raise UserError(
                    "Trying to generate a single XML payment group for payments with different partners."
                )

            partner_payment.sdd_xml_gen_payment(company_id, mandate.partner_id,
                                                partner_payment.name[:35],
                                                PmtInf)
Exemple #7
0
    def _sdd_xml_gen_payment_group(self, company_id, required_collection_date,
                                   payment_info_counter, journal,
                                   CstmrDrctDbtInitn):
        _logger.info("<-- _sdd_xml_gen_payment_group -->")
        """ Generates a group of payments in the same PmtInfo node, provided
        that they share the same journal."""
        PmtInf = create_xml_node(CstmrDrctDbtInitn, 'PmtInf')
        create_xml_node(PmtInf, 'PmtInfId', str(payment_info_counter))
        create_xml_node(PmtInf, 'PmtMtd', 'DD')
        create_xml_node(PmtInf, 'NbOfTxs', str(len(self)))
        create_xml_node(
            PmtInf, 'CtrlSum',
            float_repr(sum(x.amount for x in self), precision_digits=2)
        )  # This sum ignores thecurrency, it is used as a checksum (see SEPA rulebook)

        PmtTpInf = create_xml_node_chain(PmtInf, ['PmtTpInf', 'SvcLvl', 'Cd'],
                                         'SEPA')[0]
        tipo_mandato = ''
        for r in self:
            if r.tipo_mandato:
                tipo_mandato = r.tipo_mandato
                break
        create_xml_node_chain(PmtTpInf, ['LclInstrm', 'Cd'], tipo_mandato)
        create_xml_node(PmtTpInf, 'SeqTp', 'FRST')
        #Note: FRST refers to the COLLECTION of payments, not the type of mandate used
        #This value is only used for informatory purpose.

        create_xml_node(
            PmtInf, 'ReqdColltnDt',
            fields.Date.from_string(required_collection_date).strftime(
                "%Y-%m-%d"))
        create_xml_node_chain(
            PmtInf, ['Cdtr', 'Nm'], company_id.name[:70]
        )  # SEPA regulation gives a maximum size of 70 characters for this field
        create_xml_node_chain(PmtInf, ['CdtrAcct', 'Id', 'IBAN'],
                              journal.bank_account_id.sanitized_acc_number)
        create_xml_node_chain(PmtInf, ['CdtrAgt', 'FinInstnId', 'BIC'],
                              journal.bank_id.bic)

        CdtrSchmeId_Othr = create_xml_node_chain(
            PmtInf, ['CdtrSchmeId', 'Id', 'PrvtId', 'Othr', 'Id'],
            company_id.sdd_creditor_identifier)[-2]
        create_xml_node_chain(CdtrSchmeId_Othr, ['SchmeNm', 'Prtry'], 'SEPA')

        for payment in self:
            payment.sdd_xml_gen_payment(company_id, payment.partner_id,
                                        payment.name[:35], PmtInf)