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
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
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
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
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