def _compute_scan_line_list(self):
        """Generate a list containing all element of scan line

        the element are grouped by char or symbol

        This will allows the free placment of each element
        and enable a fine tuning of spacing

        :return: a list of sting representing the scan bar

        :rtype: list
        """
        self.ensure_one()
        line = []
        if not self._can_generate(self.move_line_id):
            return []
        justified_amount = '01%s' % ('%.2f' % self.amount_total).replace(
            '.', '').rjust(10, '0')
        line += [char for char in mod10r(justified_amount)]
        line.append('>')
        line += [char for char in self.reference.replace(" ", "")]
        line.append('+')
        line.append(' ')
        bank = self.move_line_id.invoice.partner_bank_id.get_account_number()
        account_components = bank.split('-')
        if len(account_components) != 3:
            raise Warning(
                _('Please enter a correct postal number like: '
                  '01-23456-1'))
        bank_identifier = "%s%s%s" % (account_components[0],
                                      account_components[1].rjust(
                                          6, '0'), account_components[2])
        line += [car for car in bank_identifier]
        line.append('>')
        return line
示例#2
0
    def _create_record(self, line):
        """Create a v11 record dict
        :param line: raw v11 line
        :type line: str

        :return: current line dict representation
        :rtype: dict

        """
        amount = self._get_line_amount(line)
        cost = self._get_line_cost(line)
        record = {
            'reference': line[12:39],
            'amount': amount,
            'date': time.strftime(
                '%Y-%m-%d',
                time.strptime(line[65:71], '%y%m%d')
            ),
            'cost': cost,
        }

        if record['reference'] != mod10r(record['reference'][:-1]):
            raise exceptions.UserError(
                _('Recursive mod10 is invalid for reference: %s') %
                record['reference']
            )
        return record
    def compute_ref(self):
        """Retrieve ESR/BVR reference from move line in order to print it

        Returns False when no BVR reference should be generated.  No
        reference is generated when a transaction reference already
        exists for the line (likely been generated by a payment service).
        """
        if not self._can_generate(self.move_line_id):
            return ''
        move_line = self.move_line_id
        # We sould not use technical id but will keep it for historical reason
        move_number = str(move_line.id)
        ad_number = self._get_adherent_number()
        if move_line.invoice.number:
            compound = move_line.invoice.number + str(move_line.id)
            move_number = self._compile_get_ref.sub('', compound)
        reference = mod10r(ad_number +
                           move_number.rjust(26 - len(ad_number), '0'))
        self.reference = self._space(reference)
        return reference
示例#4
0
    def _create_record(self, line):
        """Create a v11 record dict
        :param line: raw v11 line
        :type line: str

        :return: current line dict representation
        :rtype: dict

        """
        amount = self._get_line_amount(line)
        cost = self._get_line_cost(line)
        record = {
            "reference": line[12:39],
            "amount": amount,
            "date": time.strftime("%Y-%m-%d", time.strptime(line[65:71], "%y%m%d")),
            "cost": cost,
        }

        if record["reference"] != mod10r(record["reference"][:-1]):
            raise exceptions.Warning(_("Recursive mod10 is invalid for reference: %s") % record["reference"])
        return record
示例#5
0
    def postfinance_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None):
        # postfinance_partner_values = dict(partner_values)
        # postfinance_partner_values.update({
        #         'esr_reference_number': '',
        #         'esr_customer_number': '',
        #         'esr_code_line': '',
        #     })

        # HINT: Address Format
        # Schuldneradressen sind immer in einem Block, also ohne Leerzeilen zu drucken.
        # Es duerfen keine Zusatzangaben angebracht ­werden
        # Schriftart: OCR-B1-Schrift

        # Get Sale Order
        salesorder_obj = self.pool.get('sale.order')
        salesorder_id = salesorder_obj.search(cr, SUPERUSER_ID,
                                              [('name', '=', tx_values.get('reference')), ], context=context)
        assert len(salesorder_id) == 1, \
            'ERROR: None or more than one Sales Order with name %s found!' % tx_values.get('reference')
        salesorder = salesorder_obj.browse(cr, SUPERUSER_ID, salesorder_id, context=context)

        # Get Currency from Sales Order
        currency_iso_code = salesorder.currency_id.name
        assert currency_iso_code in ['EUR', 'CHF'], 'ERROR: ESR Currency not EUR or CHF: %s' % currency_iso_code

        # Get Postfinance ESR Customer Number for the Sales Order Currency
        if not salesorder.company_id.currency_id:
            raise Exception('ERROR: No Default Currency found for Company %s' % salesorder.company_id.name)

        esr_customer_number = str()
        for bank_account in salesorder.company_id.bank_ids:
            # Use currency from bank account or if none found it has to be the default one from the company
            # (This is needed for the standard case: addon multy_currency not installed)
            currency_id = salesorder.company_id.currency_id
            if bank_account.currency_id:
                currency_id = bank_account.currency_id
            # Get the esr_customer_number
            if salesorder.currency_id == currency_id and bank_account.esr_customer_number:
                assert esr_customer_number == '', \
                    'ERROR: More than one ESR-Customer-Number found for %s Bank Accounts!' % currency_iso_code
                esr_customer_number = bank_account.esr_customer_number
        assert esr_customer_number, \
            'ERROR: Postfinance ESR Customer Number not found in %s Bank Accounts!' % currency_iso_code

        # Check Postfinance ESR Customer-Number
        # -------------------------------------
        # VV-XXX-P
        # VV = ESR Code ACHTUNG: ist NICHT das Selbe wie Transaktionsartcodes!
        # 01 = CHF
        # 03 = EUR
        # XXX = Ordnungsnummer (Kundennummer der Firma bei Postfinanze) (OHNE! vorlaufende Nullen)
        # P = Prüfziffer
        pattern = '([0-9]+)-([0-9]+)-([0-9]?)'
        try:
            esr_code = re.search(pattern, esr_customer_number).group(1)
            esr_customer = re.search(pattern, esr_customer_number).group(2)
            esr_customer_number_check = re.search(pattern, esr_customer_number).group(3)
        except:
            raise Exception('ERROR: Postfinance-ESR-Customer-Number %s has a wrong format!' % esr_customer_number)

        esr_customer_number_standard = mod10r(esr_code + '{0:06d}'.format(int(esr_customer)))

        assert esr_customer_number_standard[-1] == esr_customer_number_check, \
            'ERROR: Postfinance-ESR-Customer-Number %s has a wrong check number! Should be %s' % \
            (esr_customer_number, esr_customer_number_standard[-1])
        if currency_iso_code == 'EUR':
            assert esr_code == '03', 'ERROR: esr_code %s but currency EUR. Must be 03!' % esr_code
        if currency_iso_code == 'CHF':
            assert esr_code == '01', 'ERROR: esr_code %s but currency CHF. Must be 01!' % esr_code

        # Generate Kodierzeile Anfang
        # ---------------------------
        # VVXXXXXXXXXXP
        #   VV = Transaktionsartcodes für Record Typ 4 (ESR in CHF und EUR)
        #   01 = ESR Normal in CHF
        #   21 = ESR Normal in EUR
        #   XXXXXXXXXX = Betrag mit 2 Kommastellen !!!inkl. vorlaufende Nullen!!!
        #   P = Prüfziffer (MOD10r)
        #
        # HINT: Currency in EUR or CHF already asserted above!
        transaction_type = '01' if currency_iso_code == 'CHF' else '21'
        # HINT: CHF muessen auf 00 oder 05 Rappen gerundet werden (Schweizer Norm)
        # TODO: Check if Rounding to 05 is working for CH
        amountstring_2digits = str('{0:.2f}'.format(float_round(tx_values.get('amount'), 2))).replace('.', '')
        esr_code_line_start = mod10r(transaction_type + '{0:010d}'.format(int(amountstring_2digits)))
        assert len(esr_code_line_start) == 13, 'ERROR: ESR Code Line start is not 13 Char long but %s!' % \
                                               len(esr_code_line_start)

        # Generate esr_reference_number:
        # ------------------
        # AAAAAXXXXXXXXXXXXXXXXXXXXXP (26 Stellen + P = 27 Stellen)
        #   AAAAA = Instance Base Port
        #   XXXXXXXXXXXXXXXXXXXXX = Sales Order Number
        port = salesorder.company_id.instance_base_port
        assert len(port) == 5, "ERROR: Field instance_base_port for company not set or not 5 char long: %s" % port
        so_number = ''.join(re.findall(r'\d+', salesorder.name))
        so_number = '{0:021d}'.format(int(so_number))
        esr_reference_number = mod10r(port + so_number)

        # Generate Kodierzeile Ende (=Postfinance ESR Number)
        # -------------------------
        # VVXXXXXXP
        #   VV = ESR Typ (Code)
        #   XXXXXX = Ordnungsnummer !!!inkl. vorlaufende Nullen!!! (Kundennummer der Firma bei Postfinanze)
        #   P = Prüfziffer (MOD10r)
        esr_code_line = esr_code_line_start + '>' + esr_reference_number + '+ ' + esr_customer_number_standard + '>'
        print esr_code_line

        # Update Dict
        tx_values.update({
                'esr_reference_number': esr_reference_number,
                'esr_customer_number': esr_customer_number,
                'esr_code_line': esr_code_line,
            })

        return partner_values, tx_values
示例#6
0
    def draw_christmas(self,
                       partner,
                       a4=False,
                       out_format='PDF',
                       scale=None,
                       b64=False,
                       report_name=None):
        """Generate the payment slip image
        :param a4: If set to True will print on slip on a A4 paper format
        :type a4: bool

        :param out_format: output format at current time only PDF is supported
        :type out_format: str

        :param scale: scale quadratic ration
        :type scale: float

        :param b64: If set to True the output image string
                    will be encoded to base64

        :return: slip image string
        :rtype: str
        """
        if out_format != 'PDF':
            raise NotImplementedError('Only PDF payment slip are supported')
        partner.ensure_one()
        lang = partner.lang
        self = self.with_context(lang=lang)
        company = self.env.user.company_id
        print_settings = self._get_settings(report_name)
        self._register_fonts()
        default_font = self._get_text_font()
        small_font = self._get_samll_text_font()
        # amount_font = self._get_amount_font()
        scan_font = self._get_scan_line_text_font(company)
        bank_acc = self.env['res.partner.bank'].search(
            [('acc_number', '=', '01-44443-7')], limit=1)
        if a4:
            canvas_size = (595.27, 841.89)
        else:
            canvas_size = (595.27, 286.81)
        with contextlib.closing(StringIO.StringIO()) as buff:
            canvas = Canvas(buff, pagesize=canvas_size, pageCompression=None)
            self._draw_background(canvas, print_settings)
            canvas.setFillColorRGB(*self._fill_color)
            if a4:
                initial_position = (0.05 * inch, 4.50 * inch)
                self._draw_description_line(canvas, print_settings,
                                            initial_position, default_font)
            initial_position = (0.05 * inch, 1.4 * inch)
            self._draw_address(canvas, print_settings, initial_position,
                               default_font, partner)
            initial_position = (4.86 * inch, 2.2 * inch)
            self._draw_address(canvas, print_settings, initial_position,
                               default_font, partner)
            reference = mod10r('00 00000 00' + partner.ref[0:4] + ' ' +
                               partner.ref[3:] + '0 0000' + '7 ' + '0023')
            self._draw_ref(canvas, print_settings, (4.9 * inch, 2.70 * inch),
                           default_font, reference)
            self._draw_recipe_ref(canvas, print_settings,
                                  (0.05 * inch, 1.6 * inch), small_font,
                                  reference)
            if bank_acc.print_bank:
                self._draw_bank(canvas, print_settings,
                                (0.05 * inch, 3.7 * inch), default_font,
                                bank_acc.bank)
                self._draw_bank(canvas, print_settings,
                                (2.45 * inch, 3.7 * inch), default_font,
                                bank_acc.bank)
            else:
                print_settings.bvr_add_vert += 0.15
                print_settings.bvr_message_vert += 0.1
            if bank_acc.print_partner:
                if (bank_acc.print_account or bank_acc.bvr_adherent_num):
                    initial_position = (0.05 * inch, 3.4 * inch)
                else:
                    initial_position = (0.05 * inch, 3.75 * inch)
                self._draw_address(canvas, print_settings, initial_position,
                                   default_font, partner)
                if (bank_acc.print_account or bank_acc.bvr_adherent_num):
                    initial_position = (2.45 * inch, 3.4 * inch)
                else:
                    initial_position = (2.45 * inch, 3.75 * inch)
                self._draw_address(canvas, print_settings, initial_position,
                                   default_font, partner)
            num_car, frac_car = ("%.2f" % self.amount_total).split('.')
            # ################ Do not print any amount ##################
            # self._draw_amount(canvas, print_settings,
            #                   (1.48 * inch, 2.0 * inch),
            #                   amount_font, num_car)
            # self._draw_amount(canvas, print_settings,
            #                   (2.14 * inch, 2.0 * inch),
            #                   amount_font, frac_car)
            # self._draw_amount(canvas, print_settings,
            #                   (3.88 * inch, 2.0 * inch),
            #                   amount_font, num_car)
            # self._draw_amount(canvas, print_settings,
            #                   (4.50 * inch, 2.0 * inch),
            #                   amount_font, frac_car)
            if bank_acc.print_account:
                self._draw_bank_account(canvas, print_settings,
                                        (1 * inch, 2.35 * inch), default_font,
                                        bank_acc.get_account_number())
                self._draw_bank_account(canvas, print_settings,
                                        (3.4 * inch, 2.35 * inch),
                                        default_font,
                                        bank_acc.get_account_number())
            self._draw_message_christmas(canvas, print_settings,
                                         (0.05 * inch, 2.6 * inch),
                                         default_font, partner)
            self._draw_message_christmas(canvas, print_settings,
                                         (2.45 * inch, 2.6 * inch),
                                         default_font, partner)
            self._draw_scan_line_christmas(
                canvas, print_settings,
                (8.26 * inch - 4 / 10 * inch, 4 / 6 * inch), scan_font,
                reference, bank_acc)
            self._draw_hook(canvas, print_settings)
            canvas.showPage()
            canvas.save()
            img_stream = buff.getvalue()
            if b64:
                img_stream = base64.encodestring(img_stream)
            return img_stream