def _get_ref(self, inv): """Retrieve ESR/BVR reference form invoice in order to print it""" res = '' if inv.partner_bank_id.bvr_adherent_num: res = inv.partner_bank_id.bvr_adherent_num invoice_number = '' if inv.number: invoice_number = self._compile_get_ref.sub('', inv.number) return mod10r(res + invoice_number.rjust(26-len(res), '0'))
def _check_9_pos_postal_num(self, number): """ check if a postal number in format xx-xxxxxx-x is correct, return true if it matches the pattern and if check sum mod10 is ok """ from tools import mod10r pattern = r'^[0-9]{2}-[0-9]{1,6}-[0-9]$' if not re.search(pattern, number): return False num, checksum = (number.replace('-','')[:-1], number[-1:]) return mod10r(num)[-1:] == checksum
def _check_bvr(self, cr, uid, ids): """ Function to validate a bvr reference like : 0100054150009>132000000000000000000000014+ 1300132412> The validation is based on l10n_ch """ invoices = self.browse(cr, uid, ids) for invoice in invoices: if invoice.reference_type == 'bvr': if not invoice.reference: return False ## I need help for this bug because in this case # <010001000060190> 052550152684006+ 43435> # the reference 052550152684006 do not match modulo 10 # if mod10r(invoice.reference[:-1]) != invoice.reference and \ len(invoice.reference) == 15: return True # if mod10r(invoice.reference[:-1]) != invoice.reference: return False return True
def _check_bvr(self, cursor, uid, ids): """ Function to validate a bvr reference like : 0100054150009>132000000000000000000000014+ 1300132412> The validation is based on l10n_ch """ invoices = self.browse(cursor, uid, ids) for invoice in invoices: if invoice.reference_type == 'bvr': if not invoice.reference: return False ## # <010001000060190> 052550152684006+ 43435> # This references type are no longer supported by PostFinance # if mod10r(invoice.reference[:-1]) != invoice.reference and \ len(invoice.reference) == 15: return True # if mod10r(invoice.reference[:-1]) != invoice.reference: return False return True
def _check_bvr(self, cr, uid, ids): """ Function to validate a bvr reference like : 0100054150009>132000000000000000000000014+ 1300132412> The validation is based on l10n_ch """ invoices = self.browse(cr,uid,ids) for invoice in invoices: if invoice.reference_type == 'bvr': if not invoice.reference: return False ## I need help for this bug because in this case # <010001000060190> 052550152684006+ 43435> # the reference 052550152684006 do not match modulo 10 # if mod10r(invoice.reference[:-1]) != invoice.reference and \ len(invoice.reference) == 15: return True # if mod10r(invoice.reference[:-1]) != invoice.reference: return False return True
def _check_9_pos_postal_num(self, number): """ check if a postal number in format xx-xxxxxx-x is correct, return true if it matches the pattern and if check sum mod10 is ok """ 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 validate_global_context_dict(self): super(record_gt826, self).validate_global_context_dict() if not self.global_values['reference']: raise except_osv( _('Error'), _('You must provide a BVR reference' 'number \n for the line: %s') % self.pline.name) self.global_values['reference'] = self.global_values[ 'reference'].replace(' ', '') if self.is_9_pos_adherent: if len(self.global_values['reference']) > 27: raise except_osv( _('Error'), _('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(self.global_values['reference'] [:-1]) != self.global_values['reference']: raise except_osv( _('Error'), _('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'] = self.global_values[ 'reference'].rjust(27, '0') else: # reference of BVR adherent with 5 positions number # have 15 positions references if len(self.global_values['reference']) > 15: raise except_osv( _('Error'), _('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____________ self.global_values['reference'] = self.global_values[ 'reference'].rjust(15, '0').ljust(27, ' ') if not self.global_values['partner_bvr']: raise except_osv( _('Error'), _('You must provide a BVR number\n' 'for the bank account: %s' 'on line: %s') % (self.pline.bank_id.get_account_number(), self.pline.name))
def validate_global_context_dict(self): super(record_gt826, self).validate_global_context_dict() if not self.global_values['reference']: raise except_osv(_('Error'), _('You must provide a BVR reference' 'number \n for the line: %s') % self.pline.name) self.global_values['reference'] = self.global_values['reference'].replace(' ', '') if self.is_9_pos_adherent: if len(self.global_values['reference']) > 27: raise except_osv(_('Error'), _('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(self.global_values['reference'][:-1]) != self.global_values['reference']: raise except_osv(_('Error'), _('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'] = self.global_values['reference'].rjust(27, '0') else: # reference of BVR adherent with 5 positions number # have 15 positions references if len(self.global_values['reference']) > 15: raise except_osv(_('Error'), _('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____________ self.global_values['reference'] = self.global_values['reference'].rjust(15, '0').ljust(27, ' ') if not self.global_values['partner_bvr']: raise except_osv(_('Error'), _('You must provide a BVR number\n' 'for the bank account: %s' 'on line: %s') % (self.pline.bank_id.get_account_number(), self.pline.name))
def _create_dta(obj, cr, uid, data, context): """Generate DTA file""" v = {} v["uid"] = unicode(uid) v["creation_date"] = unicode(time.strftime("%y%m%d")) dta = "" pool = pooler.get_pool(cr.dbname) payment_obj = pool.get("payment.order") attachment_obj = pool.get("ir.attachment") payment = payment_obj.browse(cr, uid, data["id"], context=context) if not payment.mode or payment.mode.type.code != "dta": raise wizard.except_wizard(_("Error"), _("No payment mode or payment type code invalid.")) bank = payment.mode.bank_id if not bank: raise wizard.except_wizard(_("Error"), _("No bank account for the company.")) v["comp_bank_name"] = bank.bank and bank.bank.name or False v["comp_bank_clearing"] = bank.bank.clearing if not v["comp_bank_clearing"]: raise wizard.except_wizard(_("Error"), _("You must provide a Clearing Number for your bank account.")) user = pool.get("res.users").browse(cr, uid, [uid])[0] company = user.company_id co_addr = company.partner_id.address[0] v["comp_country"] = co_addr.country_id and co_addr.country_id.name or u"" v["comp_street"] = co_addr.street or u"" v["comp_zip"] = co_addr.zip v["comp_city"] = co_addr.city v["comp_name"] = co_addr.name v["comp_dta"] = bank.dta_code or u"" v["comp_bank_number"] = bank.acc_number or u"" if bank.iban: v["comp_bank_iban"] = bank.iban.replace(u" ", u"") or u"" else: v["comp_bank_iban"] = "" if not v["comp_bank_iban"]: raise wizard.except_wizard(_("Error"), _("No IBAN for the company bank account.")) dta_line_obj = pool.get("account.dta.line") res_partner_bank_obj = pool.get("res.partner.bank") seq = 1 amount_tot = 0 amount_currency_tot = 0 for pline in payment.line_ids: if not pline.bank_id: raise wizard.except_wizard(_("Error"), _("No bank account defined\n" + "on line: %s") % pline.name) if not pline.bank_id.bank: raise wizard.except_wizard( _("Error"), _("No bank defined\n" + "for the bank account: %s\n" + "on the partner: %s\n" + "on line: %s") + (pline.bank_id.state, pline.partner_id.name, pline.name), ) acc_name = res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] v["sequence"] = unicode(seq).rjust(5).replace(u" ", u"0") v["amount_to_pay"] = unicode(pline.amount_currency).replace(u".", u",") v["number"] = pline.name v["currency"] = pline.currency.code v["partner_bank_name"] = pline.bank_id.bank.name or False v["partner_bank_clearing"] = pline.bank_id.bank.clearing or False if not v["partner_bank_name"]: raise wizard.except_wizard( _("Error"), _("No bank name defined\n" + "for the bank account: %s\n" + "on the partner: %s\n" + "on line: %s") % (pline.bank_id.state, pline.partner_id.name, pline.name), ) v["partner_bank_iban"] = pline.bank_id.iban or False v["partner_bank_number"] = ( pline.bank_id.acc_number and pline.bank_id.acc_number.replace(u".", u"").replace(u"-", u"") or False ) v["partner_post_number"] = ( pline.bank_id.post_number and pline.bank_id.post_number.replace(u".", u"").replace(u"-", u"") or False ) v["partner_bvr"] = pline.bank_id.bvr_number or u"" if v["partner_bvr"]: v["partner_bvr"] = v["partner_bvr"].replace(u"-", u"") if len(v["partner_bvr"]) < 9: v["partner_bvr"] = v["partner_bvr"][:2] + "0" * (9 - len(v["partner_bvr"])) + v["partner_bvr"][2:] if pline.bank_id.bank: v["partner_bank_city"] = pline.bank_id.bank.city or False v["partner_bank_street"] = pline.bank_id.bank.street or u"" v["partner_bank_zip"] = pline.bank_id.bank.zip or u"" v["partner_bank_country"] = pline.bank_id.bank.country and pline.bank_id.bank.country.name or u"" v["partner_bank_code"] = pline.bank_id.bank.bic v["reference"] = pline.move_line_id.ref # Add support for owner of the account if exists.. if pline.bank_id.owner_name: v["partner_name"] = pline.bank_id.owner_name else: v["partner_name"] = pline.partner_id and pline.partner_id.name or u"" if pline.partner_id and pline.partner_id.address and pline.partner_id.address[0]: v["partner_street"] = pline.partner_id.address[0].street v["partner_city"] = pline.partner_id.address[0].city v["partner_zip"] = pline.partner_id.address[0].zip # If iban => country=country code for space reason elec_pay = pline.bank_id.state # Bank type if elec_pay == "iban": v["partner_country"] = ( pline.partner_id.address[0].country_id and pline.partner_id.address[0].country_id.code + u"-" or u"" ) else: v["partner_country"] = ( pline.partner_id.address[0].country_id and pline.partner_id.address[0].country_id.name or "" ) else: v["partner_street"] = u"" v["partner_city"] = u"" v["partner_zip"] = u"" v["partner_country"] = u"" raise wizard.except_wizard( "Error", "No address defined \n" + "for the partner: " + pline.partner_id.name + "\n" + "on line: " + pline.name, ) if pline.order_id.date_planned: date_value = mx.DateTime.strptime(pline.order_id.date_planned, "%Y-%m-%d") elif pline.date: date_value = mx.DateTime.strptime(pline.date, "%Y-%m-%d") else: date_value = mx.DateTime.now() v["date_value"] = unicode(date_value.strftime("%y%m%d")) # si compte iban -> iban (836) # si payment structure -> bvr (826) # si non -> (827) if elec_pay == "dta_iban": # If iban => country=country code for space reason v["comp_country"] = co_addr.country_id and co_addr.country_id.code + "-" or "" record_type = RecordGt836 if not v["partner_bank_iban"]: raise wizard.except_wizard( _("Error"), _("No IBAN defined \n" + "for the bank account: %s\n" + "on line: %s") % (acc_name, pline.name), ) if v["partner_bank_code"]: # bank code is swift (BIC address) v["option_id_bank"] = u"A" v["partner_bank_ident"] = v["partner_bank_code"] elif v["partner_bank_city"]: v["option_id_bank"] = u"D" v["partner_bank_ident"] = ( v["partner_bank_name"] + " " + v["partner_bank_street"] + " " + v["partner_bank_zip"] + " " + v["partner_bank_city"] + " " + v["partner_bank_country"] ) else: raise wizard.except_wizard( _("Error"), _( "You must provide the bank city " + "and the bic code for the partner bank: \n %s\n" + "on line: %s" ) % (acc_name, pline.name), ) elif elec_pay == "bvrbank" or elec_pay == "bvrpost": from tools import mod10r if v["reference"]: v["reference"] = v["reference"].replace(" ", "").rjust(27).replace(u" ", u"0") if not v["reference"] or ( mod10r(v["reference"][:-1]) != v["reference"] and not len(v["reference"]) == 15 ): raise wizard.except_wizard( _("Error"), _("You must provide " + "a valid BVR reference number \n" + "for the line: %s") % pline.name, ) if not v["partner_bvr"]: raise wizard.except_wizard( _("Error"), _("You must provide a BVR number\n" + "for the bank account: %s" + "on line: %s") % (acc_name, pline.name), ) record_type = RecordGt826 elif elec_pay == "bvbank": if not v["partner_bank_number"]: if v["partner_bank_iban"]: v["partner_bank_number"] = v["partner_bank_iban"] else: raise wizard.except_wizard( _("Error"), _("You must provide " + "a bank number \n" + "for the partner bank: %s\n" + "on line: %s") % (acc_name, pline.name), ) if not v["partner_bank_clearing"]: raise wizard.except_wizard( _("Error"), _("You must provide " + "a Clearing Number\n" + "for the partner bank: %s\n" + "on line %s") % (acc_name, pline.name), ) v["partner_bank_number"] = "/C/" + v["partner_bank_number"] record_type = RecordGt827 elif elec_pay == "bvpost": if not v["partner_post_number"]: raise wizard.except_wizard( _("Error"), _("You must provide " + "a post number \n" + "for the partner bank: %s\n" + "on line: %s") % (acc_name, pline.name), ) v["partner_bank_clearing"] = "" v["partner_bank_number"] = "/C/" + v["partner_post_number"] record_type = RecordGt827 else: raise wizard.except_wizard( _("Error"), _("The Bank type %s of the bank" + "account: %s is not supported") % (elec_pay, acc_name) ) dta_line = record_type(v).generate() dta = dta + dta_line amount_tot += pline.amount amount_currency_tot += pline.amount_currency seq += 1 # segment total v["amount_total"] = unicode(amount_currency_tot).replace(u".", u",") v["sequence"] = unicode(seq).rjust(5).replace(u" ", u"0") if dta: dta = dta + RecordGt890(v).generate() dta_data = base64.encodestring(dta) payment_obj.set_done(cr, uid, data["id"], context) attachment_obj.create( cr, uid, { "name": "DTA", "datas": dta_data, "datas_fname": "DTA.txt", "res_model": "payment.order", "res_id": data["id"], }, context=context, ) return {"dta": dta_data}
def _create_dta(obj, cr, uid, data, context=None): v = {} v['uid'] = str(uid) v['creation_date'] = time.strftime('%y%m%d') dta = '' pool = pooler.get_pool(cr.dbname) payment_obj = pool.get('payment.order') attachment_obj = pool.get('ir.attachment') if context is None: context = {} payment = payment_obj.browse(cr, uid, data['id'], context=context) # if payment.state != 'done': # raise osv.except_osv(_('Order not confirmed'), # _('Please confirm it')) if not payment.mode: raise osv.except_osv(_('Error!'), _('No payment mode.')) bank = payment.mode.bank_id if not bank: raise osv.except_osv(_('Error!'), _('No bank account for the company.')) v['comp_bank_name']= bank.bank and bank.bank.name or False v['comp_bank_clearing'] = bank.bank.clearing if not v['comp_bank_clearing']: raise osv.except_osv(_('Error!'), _('You must provide a Clearing Number for your bank account.')) user = pool.get('res.users').browse(cr,uid,[uid])[0] company = user.company_id #XXX dirty code use get_addr co_addr = company.partner_id v['comp_country'] = co_addr.country_id and co_addr.country_id.name or '' v['comp_street'] = co_addr.street or '' v['comp_zip'] = co_addr.zip v['comp_city'] = co_addr.city v['comp_name'] = co_addr.name v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice # iban and account number are the same field and depends only on the type of account v['comp_bank_iban'] = v['comp_bank_number'] = bank.acc_number or '' #if bank.iban: # v['comp_bank_iban'] = bank.iban.replace(' ','') or '' #else: # v['comp_bank_iban'] = '' if not v['comp_bank_iban']: raise osv.except_osv(_('Error!'), _('No IBAN for the company bank account.')) res_partner_bank_obj = pool.get('res.partner.bank') seq = 1 amount_tot = 0 amount_currency_tot = 0 for pline in payment.line_ids: if not pline.bank_id: raise osv.except_osv(_('Error!'), _('No bank account defined\n' \ 'on line: %s') % pline.name) if not pline.bank_id.bank: raise osv.except_osv(_('Error!'), _('No bank defined\n' \ 'for the bank account: %s\n' \ 'on the partner: %s\n' \ 'on line: %s') + (pline.bank_id.state, pline.partner_id.name, pline.name)) v['sequence'] = str(seq).rjust(5).replace(' ', '0') v['amount_to_pay']= str(pline.amount_currency).replace('.', ',') v['number'] = pline.name v['currency'] = pline.currency.name v['partner_bank_name'] = pline.bank_id.bank.name or False v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False if not v['partner_bank_name'] : raise osv.except_osv(_('Error!'), _('No bank name defined\n' \ 'for the bank account: %s\n' \ 'on the partner: %s\n' \ 'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name)) v['partner_bank_iban'] = pline.bank_id.acc_number or False v['partner_bank_number'] = pline.bank_id.acc_number \ and pline.bank_id.acc_number.replace('.','').replace('-','') \ or False v['partner_post_number']= pline.bank_id.post_number \ and pline.bank_id.post_number.replace('.', '').replace('-', '') \ or False v['partner_bvr'] = pline.bank_id.post_number or '' if v['partner_bvr']: is_9_pos_adherent = None # if adherent bvr number is a 9 pos number # add 0 to fill 2nd part plus remove '-' # exemple: 12-567-C becomes 12000567C if _is_9_pos_bvr_adherent(v['partner_bvr']): parts = v['partner_bvr'].split('-') parts[1] = parts[1].rjust(6, '0') v['partner_bvr'] = ''.join(parts) is_9_pos_adherent = True # add 4*0 to bvr adherent number with 5 pos # exemple: 12345 becomes 000012345 elif len(v['partner_bvr']) == 5: v['partner_bvr'] = v['partner_bvr'].rjust(9, '0') is_9_pos_adherent = False else: raise osv.except_osv(_('Error!'), _('Wrong postal number format.\n' 'It must be 12-123456-9 or 12345 format')) if pline.bank_id.bank: v['partner_bank_city'] = pline.bank_id.bank.city or False v['partner_bank_street'] = pline.bank_id.bank.street or '' v['partner_bank_zip'] = pline.bank_id.bank.zip or '' v['partner_bank_country'] = pline.bank_id.bank.country and \ pline.bank_id.bank.country.name or '' v['partner_bank_code'] = pline.bank_id.bank.bic v['reference'] = pline.move_line_id.ref # Add support for owner of the account if exists.. if pline.bank_id.owner_name: v['partner_name'] = pline.bank_id.owner_name else: v['partner_name'] = pline.partner_id and pline.partner_id.name or '' if pline.partner_id and pline.partner_id: v['partner_street'] = pline.partner_id.street v['partner_city'] = pline.partner_id.city v['partner_zip'] = pline.partner_id.zip # If iban => country=country code for space reason elec_pay = pline.bank_id.state #Bank type if elec_pay == 'iban': v['partner_country']= pline.partner_id.country_id \ and pline.partner_id.country_id.code+'-' \ or '' else: v['partner_country']= pline.partner_id.country_id \ and pline.partner_id.country_id.name \ or '' else: v['partner_street'] ='' v['partner_city']= '' v['partner_zip']= '' v['partner_country']= '' raise osv.except_osv('Error', 'No address defined \n' \ 'for the partner: ' + pline.partner_id.name + '\n' \ 'on line: ' + pline.name) if pline.order_id.date_scheduled: date_value = datetime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d') elif pline.date: date_value = datetime.strptime(pline.date, '%Y-%m-%d') else: date_value = datetime.now() v['date_value'] = date_value.strftime("%y%m%d") # si compte iban -> iban (836) # si payment structure -> bvr (826) # si non -> (827) if elec_pay == 'iban': # If iban => country=country code for space reason v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or '' record_type = record_gt836 if not v['partner_bank_iban']: raise osv.except_osv(_('Error!'), _('No IBAN defined \n' \ 'for the bank account: %s\n' + \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) if v['partner_bank_code'] : # bank code is swift (BIC address) v['option_id_bank']= 'A' v['partner_bank_ident']= v['partner_bank_code'] elif v['partner_bank_city']: v['option_id_bank']= 'D' v['partner_bank_ident']= v['partner_bank_name'] \ + ' ' + v['partner_bank_street'] \ + ' ' + v['partner_bank_zip'] \ + ' ' + v['partner_bank_city'] \ + ' ' + v['partner_bank_country'] else: raise osv.except_osv(_('Error!'), _('You must provide the bank city ' 'or the bic code for the partner bank: \n %d\n' + \ 'on line: %s') %(res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1], pline.name)) elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost': from tools import mod10r if not v['reference']: raise osv.except_osv(_('Error!'), _('You must provide ' \ 'a BVR reference number \n' \ 'for the line: %s') % pline.name) v['reference'] = v['reference'].replace(' ', '') if is_9_pos_adherent: if len(v['reference']) > 27: raise osv.except_osv(_('Error!'), _('BVR reference number is not valid \n' 'for the line: %s. \n' 'Reference is too long.') % pline.name) # do a mod10 check if mod10r(v['reference'][:-1]) != v['reference']: raise osv.except_osv(_('Error!'), _('BVR reference number is not valid \n' 'for the line: %s. \n' 'Mod10 check failed.') % pline.name) # fill reference with 0 v['reference'] = v['reference'].rjust(27, '0') else: # reference of BVR adherent with 5 positions number # have 15 positions references if len(v['reference']) > 15: raise osv.except_osv(_('Error!'), _('BVR reference number is not valid \n' 'for the line: %s. \n' 'Reference is too long ' 'for this type of beneficiary.') % pline.name) # complete 15 first digit with 0 on left and complete 27 digits with trailing spaces # exemple: 123456 becomes 00000000012345____________ v['reference'] = v['reference'].rjust(15, '0').ljust(27, ' ') if not v['partner_bvr']: raise osv.except_osv(_('Error!'), _('You must provide a BVR number\n' 'for the bank account: %s' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],context)[0][1] ,pline.name)) record_type = record_gt826 elif elec_pay == 'bvbank': if not v['partner_bank_number'] : raise osv.except_osv(_('Error!'), _('You must provide ' \ 'a bank number \n' \ 'for the partner bank: %s\n' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) if not v['partner_bank_clearing']: raise osv.except_osv(_('Error!'), _('You must provide ' \ 'a Clearing Number\n' \ 'for the partner bank: %s\n' \ 'on line %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) v['partner_bank_number'] = '/C/'+v['partner_bank_number'] record_type = record_gt827 elif elec_pay == 'bvpost': if not v['partner_post_number']: raise osv.except_osv(_('Error!'), _('You must provide ' \ 'a post number \n' \ 'for the partner bank: %s\n' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] ,pline.name)) v['partner_bank_clearing']= '' v['partner_bank_number'] = '/C/'+v['partner_post_number'] record_type = record_gt827 else: raise osv.except_osv(_('Error!'), _('The Bank type %s of the bank account: %s is not supported.') \ % (elec_pay, res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1],)) dta_line = record_type(v).generate() dta = dta + dta_line amount_tot += pline.amount amount_currency_tot += pline.amount_currency seq += 1 # segment total v['amount_total'] = str(amount_currency_tot).replace('.',',') v['sequence'] = str(seq).rjust(5).replace(' ','0') if dta : dta = dta + record_gt890(v).generate() dta_data = _u2a(dta) dta_data = base64.encodestring(dta) payment_obj.set_done(cr, uid, [data['id']], context) attachment_obj.create(cr, uid, { 'name': 'DTA%s'%time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()), 'datas': dta_data, 'datas_fname': 'DTA%s.txt'%time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()), 'res_model': 'payment.order', 'res_id': data['id'], }, context=context) return dta_data
def _import(obj, cursor, user, data, context): """import the recieve file in the bank statement and do the reconciliation""" pool = pooler.get_pool(cursor.dbname) statement_line_obj = pool.get('account.bank.statement.line') statement_reconcile_obj = pool.get('account.bank.statement.reconcile') move_line_obj = pool.get('account.move.line') property_obj = pool.get('ir.property') model_fields_obj = pool.get('ir.model.fields') attachment_obj = pool.get('ir.attachment') file = data['form']['file'] statement_id = data['id'] records = [] total_amount = 0 total_cost = 0 find_total = False #we recieve the file in base 64 so we decode it for lines in base64.decodestring(file).split("\n"): # Manage files without carriage return while lines: (line, lines) = (lines[:128], lines[128:]) record = {} if line[0:3] in ('999', '995'): if find_total: raise wizard.except_wizard(_('Error'), _('Too much total record found!')) find_total = True if lines: raise wizard.except_wizard(_('Error'), _('Record found after total record!')) amount = float(line[39:49]) + (float(line[49:51]) / 100) cost = float(line[69:76]) + (float(line[76:78]) / 100) if line[2] == '5': amount *= -1 cost *= -1 if round(amount - total_amount, 2) >= 0.01 \ or round(cost - total_cost, 2) >= 0.01: raise wizard.except_wizard(_('Error'), _('Total record different from the computed!')) if int(line[51:63]) != len(records): raise wizard.except_wizard(_('Error'), _('Number record different from the computed!')) else: record = { 'reference': line[12:39], 'amount': float(line[39:47]) + (float(line[47:49]) / 100), 'date': time.strftime('%Y-%m-%d', time.strptime(line[65:71], '%y%m%d')), 'cost': float(line[96:98]) + (float(line[98:100]) / 100), } if record['reference'] != mod10r(record['reference'][:-1]): raise wizard.except_wizard(_('Error'), _('Recursive mod10 is invalid for reference: %s') % \ record['reference']) if line[2] == '5': record['amount'] *= -1 record['cost'] *= -1 total_amount += record['amount'] total_cost += record['cost'] records.append(record) model_fields_ids = model_fields_obj.search( cursor, user, [ ('name', 'in', [ 'property_account_receivable', 'property_account_payable' ] ), ('model', '=', 'res.partner'), ], context=context ) property_ids = property_obj.search(cursor, user, [ ('fields_id', 'in', model_fields_ids), ('res_id', '=', False), ], context=context) account_receivable = False account_payable = False for property in property_obj.browse(cursor, user, property_ids, context=context): if property.fields_id.name == 'property_account_receivable': account_receivable = int(property.value.split(',')[1]) elif property.fields_id.name == 'property_account_payable': account_payable = int(property.value.split(',')[1]) for record in records: # Remove the 11 first char because it can be adherent number reference = record['reference'][11:-1].lstrip('0') values = { 'name': 'IN '+ reference, 'date': record['date'], 'amount': record['amount'], 'ref': reference, 'type': (record['amount'] >= 0 and 'customer') or 'supplier', 'statement_id': statement_id, } line_ids = move_line_obj.search(cursor, user, [ ('ref', 'like', reference), ('reconcile_id', '=', False), ('account_id.type', 'in', ['receivable', 'payable']), ], order='date desc', context=context) if not line_ids: line_ids = _reconstruct_invoice_ref(cursor,user,reference,None) line2reconcile = False partner_id = False account_id = False for line in move_line_obj.browse(cursor, user, line_ids, context=context): if line.partner_id.id: partner_id = line.partner_id.id if record['amount'] >= 0: if round(record['amount'] - line.debit, 2) < 0.01: line2reconcile = line.id account_id = line.account_id.id break else: if round(line.credit + record['amount'], 2) < 0.01: line2reconcile = line.id account_id = line.account_id.id break if not account_id: if record['amount'] >= 0: account_id = account_receivable else: account_id = account_payable if not account_id : raise wizard.except_wizard(_('Error'), _('The properties account payable account receivable')) values['account_id'] = account_id values['partner_id'] = partner_id if line2reconcile: values['reconcile_id'] = statement_reconcile_obj.create( cursor, user, { 'line_ids': [(6, 0, [line2reconcile])], }, context=context ) statement_line_obj.create(cursor, user, values, context=context) attachment_obj.create(cursor, user, { 'name': 'BVR', 'datas': file, 'datas_fname': 'BVR.txt', 'res_model': 'account.bank.statement', 'res_id': statement_id, }, context=context) return {}
def _import(self, cursor, user, data, context=None): statement_line_obj = self.pool.get('account.bank.statement.line') # statement_reconcile_obj = pool.get('account.bank.statement.reconcile') voucher_obj = self.pool.get('account.voucher') voucher_line_obj = self.pool.get('account.voucher.line') move_line_obj = self.pool.get('account.move.line') property_obj = self.pool.get('ir.property') model_fields_obj = self.pool.get('ir.model.fields') attachment_obj = self.pool.get('ir.attachment') statement_obj = self.pool.get('account.bank.statement') property_obj = self.pool.get('ir.property') file = data['form']['file'] statement_id = data['id'] records = [] total_amount = 0 total_cost = 0 find_total = False if context is None: context = {} for lines in base64.decodestring(file).split("\n"): # Manage files without carriage return while lines: (line, lines) = (lines[:128], lines[128:]) record = {} if line[0:3] in ('999', '995'): if find_total: raise osv.except_osv(_('Error'), _('Too much total record found!')) find_total = True if lines: raise osv.except_osv(_('Error'), _('Record found after total record!')) amount = float(line[39:49]) + (float(line[49:51]) / 100) cost = float(line[69:76]) + (float(line[76:78]) / 100) if line[2] == '5': amount *= -1 cost *= -1 if round(amount - total_amount, 2) >= 0.01 \ or round(cost - total_cost, 2) >= 0.01: raise osv.except_osv( _('Error'), _('Total record different from the computed!')) if int(line[51:63]) != len(records): raise osv.except_osv( _('Error'), _('Number record different from the computed!')) else: record = { 'reference': line[12:39], 'amount': float(line[39:47]) + (float(line[47:49]) / 100), 'date': time.strftime('%Y-%m-%d', time.strptime(line[65:71], '%y%m%d')), 'cost': float(line[96:98]) + (float(line[98:100]) / 100), } if record['reference'] != mod10r(record['reference'][:-1]): raise osv.except_osv(_('Error'), _('Recursive mod10 is invalid for reference: %s') % \ record['reference']) if line[2] == '5': record['amount'] *= -1 record['cost'] *= -1 total_amount += record['amount'] total_cost += record['cost'] records.append(record) account_receivable = False account_payable = False statement = statement_obj.browse(cursor, user, statement_id, context=context) for record in records: # Remove the 11 first char because it can be adherent number # TODO check if 11 is the right number reference = record['reference'][11:-1].lstrip('0') values = { 'name': 'IN ' + reference, 'date': record['date'], 'amount': record['amount'], 'ref': reference, 'type': (record['amount'] >= 0 and 'customer') or 'supplier', 'statement_id': statement_id, } line_ids = move_line_obj.search( cursor, user, [ ('ref', 'like', reference), ('reconcile_id', '=', False), ('account_id.type', 'in', ['receivable', 'payable']), ], order='date desc', context=context) if not line_ids: line_ids = _reconstruct_invoice_ref(cursor, user, reference, None) partner_id = False account_id = False for line in move_line_obj.browse(cursor, user, line_ids, context=context): account_receivable = line.partner_id.property_account_receivable.id account_payable = line.partner_id.property_account_payable.id partner_id = line.partner_id.id move_id = line.move_id.id if record['amount'] >= 0: if round(record['amount'] - line.debit, 2) < 0.01: # line2reconcile = line.id account_id = line.account_id.id break else: if round(line.credit + record['amount'], 2) < 0.01: # line2reconcile = line.id account_id = line.account_id.id break context.update({'move_line_ids': line_ids}) result = voucher_obj.onchange_partner_id( cursor, user, [], partner_id, journal_id=statement.journal_id.id, price=abs(record['amount']), currency_id=statement.currency.id, ttype='receipt', date=statement.date, context=context) voucher_res = { 'type': 'receipt', 'name': values['name'], 'partner_id': partner_id, 'journal_id': statement.journal_id.id, 'account_id': result.get('account_id', statement.journal_id.default_credit_account_id.id), 'company_id': statement.company_id.id, 'currency_id': statement.currency.id, 'date': record['date'] or time.strftime('%Y-%m-%d'), 'amount': abs(record['amount']), 'period_id': statement.period_id.id } voucher_id = voucher_obj.create(cursor, user, voucher_res, context=context) values['voucher_id'] = voucher_id voucher_line_dict = False if result['value']['line_ids']: for line_dict in result['value']['line_ids']: move_line = move_line_obj.browse(cursor, user, line_dict['move_line_id'], context) if move_id == move_line.move_id.id: voucher_line_dict = line_dict if voucher_line_dict: voucher_line_dict.update({'voucher_id': voucher_id}) voucher_line_obj.create(cursor, user, voucher_line_dict, context=context) if not account_id: if record['amount'] >= 0: account_id = account_receivable else: account_id = account_payable ##If line not linked to an invoice we create a line not linked to a voucher if not account_id and not line_ids: name = "property_account_receivable" if record['amount'] < 0: name = "property_account_payable" prop = property_obj.search( cursor, user, [('name', '=', 'property_account_receivable'), ('company_id', '=', statement.company_id.id), ('res_id', '=', False)]) if prop: value = property_obj.read(cursor, user, prop[0], ['value_reference']).get( 'value_reference', False) if value: account_id = int(value.split(',')[1]) else: raise osv.except_osv( _('Error'), _('The properties account payable account receivable are not set' )) if not account_id and line_ids: raise osv.except_osv( _('Error'), _('The properties account payable account receivable are not set' )) values['account_id'] = account_id values['partner_id'] = partner_id statement_line_obj.create(cursor, user, values, context=context) attachment_obj.create(cursor, user, { 'name': 'BVR', 'datas': file, 'datas_fname': 'BVR.txt', 'res_model': 'account.bank.statement', 'res_id': statement_id, }, context=context) return {}
def _create_dta(obj, cr, uid, data, context=None): v = {} v['uid'] = str(uid) v['creation_date'] = time.strftime('%y%m%d') dta = '' pool = pooler.get_pool(cr.dbname) payment_obj = pool.get('payment.order') attachment_obj = pool.get('ir.attachment') if context is None: context = {} payment = payment_obj.browse(cr, uid, data['id'], context=context) if not payment.mode: raise osv.except_osv(_('Error'), _('No payment mode')) bank = payment.mode.bank_id if not bank: raise osv.except_osv(_('Error'), _('No bank account for the company.')) v['comp_bank_name']= bank.bank and bank.bank.name or False v['comp_bank_clearing'] = bank.bank.clearing if not v['comp_bank_clearing']: raise osv.except_osv(_('Error'), _('You must provide a Clearing Number for your bank account.')) user = pool.get('res.users').browse(cr,uid,[uid])[0] company = user.company_id #XXX dirty code use get_addr co_addr = company.partner_id.address[0] v['comp_country'] = co_addr.country_id and co_addr.country_id.name or '' v['comp_street'] = co_addr.street or '' v['comp_zip'] = co_addr.zip v['comp_city'] = co_addr.city v['comp_name'] = co_addr.name v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice v['comp_bank_number'] = bank.acc_number or '' if bank.iban: v['comp_bank_iban'] = bank.iban.replace(' ','') or '' else: v['comp_bank_iban'] = '' if not v['comp_bank_iban']: raise osv.except_osv(_('Error'), _('No IBAN for the company bank account.')) dta_line_obj = pool.get('account.dta.line') res_partner_bank_obj = pool.get('res.partner.bank') seq = 1 amount_tot = 0 amount_currency_tot = 0 for pline in payment.line_ids: if not pline.bank_id: raise osv.except_osv(_('Error'), _('No bank account defined\n' \ 'on line: %s') % pline.name) if not pline.bank_id.bank: raise osv.except_osv(_('Error'), _('No bank defined\n' \ 'for the bank account: %s\n' \ 'on the partner: %s\n' \ 'on line: %s') + (pline.bank_id.state, pline.partner_id.name, pline.name)) v['sequence'] = str(seq).rjust(5).replace(' ', '0') v['amount_to_pay']= str(pline.amount_currency).replace('.', ',') v['number'] = pline.name v['currency'] = pline.currency.name v['partner_bank_name'] = pline.bank_id.bank.name or False v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False if not v['partner_bank_name'] : raise osv.except_osv(_('Error'), _('No bank name defined\n' \ 'for the bank account: %s\n' \ 'on the partner: %s\n' \ 'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name)) v['partner_bank_iban'] = pline.bank_id.iban or False v['partner_bank_number'] = pline.bank_id.acc_number \ and pline.bank_id.acc_number.replace('.','').replace('-','') \ or False v['partner_post_number']= pline.bank_id.post_number \ and pline.bank_id.post_number.replace('.', '').replace('-', '') \ or False v['partner_bvr'] = pline.bank_id.post_number or '' if v['partner_bvr']: v['partner_bvr'] = v['partner_bvr'].replace('-','') if len(v['partner_bvr']) < 9: v['partner_bvr'] = v['partner_bvr'][:2] + '0' * \ (9 - len(v['partner_bvr'])) + v['partner_bvr'][2:] if pline.bank_id.bank: v['partner_bank_city'] = pline.bank_id.bank.city or False v['partner_bank_street'] = pline.bank_id.bank.street or '' v['partner_bank_zip'] = pline.bank_id.bank.zip or '' v['partner_bank_country'] = pline.bank_id.bank.country and \ pline.bank_id.bank.country.name or '' v['partner_bank_code'] = pline.bank_id.bank.bic v['reference'] = pline.move_line_id.ref # Add support for owner of the account if exists.. if pline.bank_id.owner_name: v['partner_name'] = pline.bank_id.owner_name else: v['partner_name'] = pline.partner_id and pline.partner_id.name or '' if pline.partner_id and pline.partner_id.address \ and pline.partner_id.address[0]: v['partner_street'] = pline.partner_id.address[0].street v['partner_city'] = pline.partner_id.address[0].city v['partner_zip'] = pline.partner_id.address[0].zip # If iban => country=country code for space reason elec_pay = pline.bank_id.state #Bank type if elec_pay == 'iban': v['partner_country']= pline.partner_id.address[0].country_id \ and pline.partner_id.address[0].country_id.code+'-' \ or '' else: v['partner_country']= pline.partner_id.address[0].country_id \ and pline.partner_id.address[0].country_id.name \ or '' else: v['partner_street'] ='' v['partner_city']= '' v['partner_zip']= '' v['partner_country']= '' raise osv.except_osv('Error', 'No address defined \n' \ 'for the partner: ' + pline.partner_id.name + '\n' \ 'on line: ' + pline.name) if pline.order_id.date_scheduled: date_value = datetime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d') elif pline.date: date_value = datetime.strptime(pline.date, '%Y-%m-%d') else: date_value = datetime.now() v['date_value'] = date_value.strftime("%y%m%d") # si compte iban -> iban (836) # si payment structure -> bvr (826) # si non -> (827) if elec_pay == 'dta_iban': # If iban => country=country code for space reason v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or '' record_type = record_gt836 if not v['partner_bank_iban']: raise osv.except_osv(_('Error'), _('No IBAN defined \n' \ 'for the bank account: %s\n' + \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) if v['partner_bank_code'] : # bank code is swift (BIC address) v['option_id_bank']= 'A' v['partner_bank_ident']= v['partner_bank_code'] elif v['partner_bank_city']: v['option_id_bank']= 'D' v['partner_bank_ident']= v['partner_bank_name'] \ + ' ' + v['partner_bank_street'] \ + ' ' + v['partner_bank_zip'] \ + ' ' + v['partner_bank_city'] \ + ' ' + v['partner_bank_country'] else: raise osv.except_osv(_('Error'), _('You must provide the bank city ' 'or the bic code for the partner bank: \n %d\n' + \ 'on line: %s') %(res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1], pline.name)) elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost': from tools import mod10r if v['reference']: v['reference'] = v['reference'].replace(' ', '').rjust(27).replace(' ', '0') if not v['reference'] \ or (mod10r(v['reference'][:-1]) != v['reference'] and \ not len(v['reference']) == 15): raise osv.except_osv(_('Error'), _('You must provide ' \ 'a valid BVR reference number \n' \ 'for the line: %s') % pline.name) if not v['partner_bvr']: raise osv.except_osv(_('Error'), _('You must provide a BVR number\n' 'for the bank account: %s' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],context)[0][1] ,pline.name)) record_type = record_gt826 elif elec_pay == 'bvbank': if not v['partner_bank_number'] : if v['partner_bank_iban'] : v['partner_bank_number']= v['partner_bank_iban'] else: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a bank number \n' \ 'for the partner bank: %s\n' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) if not v['partner_bank_clearing']: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a Clearing Number\n' \ 'for the partner bank: %s\n' \ 'on line %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) v['partner_bank_number'] = '/C/'+v['partner_bank_number'] record_type = record_gt827 elif elec_pay == 'bvpost': if not v['partner_post_number']: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a post number \n' \ 'for the partner bank: %s\n' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] ,pline.name)) v['partner_bank_clearing']= '' v['partner_bank_number'] = '/C/'+v['partner_post_number'] record_type = record_gt827 else: raise osv.except_osv(_('Error'), _('The Bank type %s of the bank account: %s is not supported') \ % (elec_pay, res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1],)) dta_line = record_type(v).generate() dta = dta + dta_line amount_tot += pline.amount amount_currency_tot += pline.amount_currency seq += 1 # segment total v['amount_total'] = str(amount_currency_tot).replace('.',',') v['sequence'] = str(seq).rjust(5).replace(' ','0') if dta : dta = dta + record_gt890(v).generate() dta_data = base64.encodestring(dta) payment_obj.set_done(cr, uid, [data['id']], context) attachment_obj.create(cr, uid, { 'name': 'DTA', 'datas': dta_data, 'datas_fname': 'DTA.txt', 'res_model': 'payment.order', 'res_id': data['id'], }, context=context) return {'dta': dta_data}
def _create_dta(obj, cr, uid, data, context=None): v = {} v['uid'] = str(uid) v['creation_date'] = time.strftime('%y%m%d') dta = '' pool = pooler.get_pool(cr.dbname) payment_obj = pool.get('payment.order') attachment_obj = pool.get('ir.attachment') if context is None: context = {} payment = payment_obj.browse(cr, uid, data['id'], context=context) # if payment.state != 'done': # raise osv.except_osv(_('Order not confirmed'), # _('Please confirm it')) if not payment.mode: raise osv.except_osv(_('Error'), _('No payment mode')) bank = payment.mode.bank_id if not bank: raise osv.except_osv(_('Error'), _('No bank account for the company.')) v['comp_bank_name'] = bank.bank and bank.bank.name or False v['comp_bank_clearing'] = bank.bank.clearing if not v['comp_bank_clearing']: raise osv.except_osv( _('Error'), _('You must provide a Clearing Number for your bank account.')) user = pool.get('res.users').browse(cr, uid, [uid])[0] company = user.company_id #XXX dirty code use get_addr co_addr = company.partner_id v['comp_country'] = co_addr.country_id and co_addr.country_id.name or '' v['comp_street'] = co_addr.street or '' v['comp_zip'] = co_addr.zip v['comp_city'] = co_addr.city v['comp_name'] = co_addr.name v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice # iban and account number are the same field and depends only on the type of account v['comp_bank_iban'] = v['comp_bank_number'] = bank.acc_number or '' #if bank.iban: # v['comp_bank_iban'] = bank.iban.replace(' ','') or '' #else: # v['comp_bank_iban'] = '' if not v['comp_bank_iban']: raise osv.except_osv(_('Error'), _('No IBAN for the company bank account.')) res_partner_bank_obj = pool.get('res.partner.bank') seq = 1 amount_tot = 0 amount_currency_tot = 0 for pline in payment.line_ids: if not pline.bank_id: raise osv.except_osv(_('Error'), _('No bank account defined\n' \ 'on line: %s') % pline.name) if not pline.bank_id.bank: raise osv.except_osv(_('Error'), _('No bank defined\n' \ 'for the bank account: %s\n' \ 'on the partner: %s\n' \ 'on line: %s') + (pline.bank_id.state, pline.partner_id.name, pline.name)) v['sequence'] = str(seq).rjust(5).replace(' ', '0') v['amount_to_pay'] = str(pline.amount_currency).replace('.', ',') v['number'] = pline.name v['currency'] = pline.currency.name v['partner_bank_name'] = pline.bank_id.bank.name or False v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False if not v['partner_bank_name']: raise osv.except_osv(_('Error'), _('No bank name defined\n' \ 'for the bank account: %s\n' \ 'on the partner: %s\n' \ 'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name)) v['partner_bank_iban'] = pline.bank_id.acc_number or False v['partner_bank_number'] = pline.bank_id.acc_number \ and pline.bank_id.acc_number.replace('.','').replace('-','') \ or False v['partner_post_number']= pline.bank_id.post_number \ and pline.bank_id.post_number.replace('.', '').replace('-', '') \ or False v['partner_bvr'] = pline.bank_id.post_number or '' if v['partner_bvr']: is_9_pos_adherent = None # if adherent bvr number is a 9 pos number # add 0 to fill 2nd part plus remove '-' # exemple: 12-567-C becomes 12000567C if _is_9_pos_bvr_adherent(v['partner_bvr']): parts = v['partner_bvr'].split('-') parts[1] = parts[1].rjust(6, '0') v['partner_bvr'] = ''.join(parts) is_9_pos_adherent = True # add 4*0 to bvr adherent number with 5 pos # exemple: 12345 becomes 000012345 elif len(v['partner_bvr']) == 5: v['partner_bvr'] = v['partner_bvr'].rjust(9, '0') is_9_pos_adherent = False else: raise osv.except_osv( _('Error'), _('Wrong postal number format.\n' 'It must be 12-123456-9 or 12345 format')) if pline.bank_id.bank: v['partner_bank_city'] = pline.bank_id.bank.city or False v['partner_bank_street'] = pline.bank_id.bank.street or '' v['partner_bank_zip'] = pline.bank_id.bank.zip or '' v['partner_bank_country'] = pline.bank_id.bank.country and \ pline.bank_id.bank.country.name or '' v['partner_bank_code'] = pline.bank_id.bank.bic v['reference'] = pline.move_line_id.ref # Add support for owner of the account if exists.. if pline.bank_id.owner_name: v['partner_name'] = pline.bank_id.owner_name else: v['partner_name'] = pline.partner_id and pline.partner_id.name or '' if pline.partner_id and pline.partner_id: v['partner_street'] = pline.partner_id.street v['partner_city'] = pline.partner_id.city v['partner_zip'] = pline.partner_id.zip # If iban => country=country code for space reason elec_pay = pline.bank_id.state #Bank type if elec_pay == 'iban': v['partner_country']= pline.partner_id.country_id \ and pline.partner_id.country_id.code+'-' \ or '' else: v['partner_country']= pline.partner_id.country_id \ and pline.partner_id.country_id.name \ or '' else: v['partner_street'] = '' v['partner_city'] = '' v['partner_zip'] = '' v['partner_country'] = '' raise osv.except_osv('Error', 'No address defined \n' \ 'for the partner: ' + pline.partner_id.name + '\n' \ 'on line: ' + pline.name) if pline.order_id.date_scheduled: date_value = datetime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d') elif pline.date: date_value = datetime.strptime(pline.date, '%Y-%m-%d') else: date_value = datetime.now() v['date_value'] = date_value.strftime("%y%m%d") # si compte iban -> iban (836) # si payment structure -> bvr (826) # si non -> (827) if elec_pay == 'iban': # If iban => country=country code for space reason v['comp_country'] = co_addr.country_id and co_addr.country_id.code + '-' or '' record_type = record_gt836 if not v['partner_bank_iban']: raise osv.except_osv(_('Error'), _('No IBAN defined \n' \ 'for the bank account: %s\n' + \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) if v['partner_bank_code']: # bank code is swift (BIC address) v['option_id_bank'] = 'A' v['partner_bank_ident'] = v['partner_bank_code'] elif v['partner_bank_city']: v['option_id_bank'] = 'D' v['partner_bank_ident']= v['partner_bank_name'] \ + ' ' + v['partner_bank_street'] \ + ' ' + v['partner_bank_zip'] \ + ' ' + v['partner_bank_city'] \ + ' ' + v['partner_bank_country'] else: raise osv.except_osv(_('Error'), _('You must provide the bank city ' 'or the bic code for the partner bank: \n %d\n' + \ 'on line: %s') %(res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1], pline.name)) elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost': from tools import mod10r if not v['reference']: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a BVR reference number \n' \ 'for the line: %s') % pline.name) v['reference'] = v['reference'].replace(' ', '') if is_9_pos_adherent: if len(v['reference']) > 27: raise osv.except_osv( _('Error'), _('BVR reference number is not valid \n' 'for the line: %s. \n' 'Reference is too long.') % pline.name) # do a mod10 check if mod10r(v['reference'][:-1]) != v['reference']: raise osv.except_osv( _('Error'), _('BVR reference number is not valid \n' 'for the line: %s. \n' 'Mod10 check failed') % pline.name) # fill reference with 0 v['reference'] = v['reference'].rjust(27, '0') else: # reference of BVR adherent with 5 positions number # have 15 positions references if len(v['reference']) > 15: raise osv.except_osv( _('Error'), _('BVR reference number is not valid \n' 'for the line: %s. \n' 'Reference is too long ' 'for this type of beneficiary.') % pline.name) # complete 15 first digit with 0 on left and complete 27 digits with trailing spaces # exemple: 123456 becomes 00000000012345____________ v['reference'] = v['reference'].rjust(15, '0').ljust(27, ' ') if not v['partner_bvr']: raise osv.except_osv(_('Error'), _('You must provide a BVR number\n' 'for the bank account: %s' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],context)[0][1] ,pline.name)) record_type = record_gt826 elif elec_pay == 'bvbank': if not v['partner_bank_number']: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a bank number \n' \ 'for the partner bank: %s\n' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) if not v['partner_bank_clearing']: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a Clearing Number\n' \ 'for the partner bank: %s\n' \ 'on line %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name)) v['partner_bank_number'] = '/C/' + v['partner_bank_number'] record_type = record_gt827 elif elec_pay == 'bvpost': if not v['partner_post_number']: raise osv.except_osv(_('Error'), _('You must provide ' \ 'a post number \n' \ 'for the partner bank: %s\n' \ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] ,pline.name)) v['partner_bank_clearing'] = '' v['partner_bank_number'] = '/C/' + v['partner_post_number'] record_type = record_gt827 else: raise osv.except_osv(_('Error'), _('The Bank type %s of the bank account: %s is not supported') \ % (elec_pay, res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1],)) dta_line = record_type(v).generate() dta = dta + dta_line amount_tot += pline.amount amount_currency_tot += pline.amount_currency seq += 1 # segment total v['amount_total'] = str(amount_currency_tot).replace('.', ',') v['sequence'] = str(seq).rjust(5).replace(' ', '0') if dta: dta = dta + record_gt890(v).generate() dta_data = _u2a(dta) dta_data = base64.encodestring(dta) payment_obj.set_done(cr, uid, [data['id']], context) attachment_obj.create( cr, uid, { 'name': 'DTA%s' % time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()), 'datas': dta_data, 'datas_fname': 'DTA%s.txt' % time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()), 'res_model': 'payment.order', 'res_id': data['id'], }, context=context) return dta_data
def _import(self, cursor, user, data, context=None): statement_line_obj = self.pool.get("account.bank.statement.line") voucher_obj = self.pool.get("account.voucher") voucher_line_obj = self.pool.get("account.voucher.line") move_line_obj = self.pool.get("account.move.line") property_obj = self.pool.get("ir.property") model_fields_obj = self.pool.get("ir.model.fields") attachment_obj = self.pool.get("ir.attachment") statement_obj = self.pool.get("account.bank.statement") property_obj = self.pool.get("ir.property") file = data["form"]["file"] if not file: raise osv.except_osv(_("User Error!"), _("Please select a file first.")) statement_id = data["id"] records = [] total_amount = 0 total_cost = 0 find_total = False if context is None: context = {} for lines in base64.decodestring(file).split("\n"): # Manage files without carriage return while lines: (line, lines) = (lines[:128], lines[128:]) record = {} if line[0:3] in ("999", "995"): if find_total: raise osv.except_osv(_("Error!"), _("Too much total record found.")) find_total = True if lines: raise osv.except_osv(_("Error!"), _("Record found after total record.")) amount = float(line[39:49]) + (float(line[49:51]) / 100) cost = float(line[69:76]) + (float(line[76:78]) / 100) if line[2] == "5": amount *= -1 cost *= -1 if round(amount - total_amount, 2) >= 0.01 or round(cost - total_cost, 2) >= 0.01: raise osv.except_osv(_("Error!"), _("Total record different from the computed.")) if int(line[51:63]) != len(records): raise osv.except_osv(_("Error!"), _("Number record different from the computed.")) else: record = { "reference": line[12:39], "amount": float(line[39:47]) + (float(line[47:49]) / 100), "date": time.strftime("%Y-%m-%d", time.strptime(line[65:71], "%y%m%d")), "cost": float(line[96:98]) + (float(line[98:100]) / 100), } if record["reference"] != mod10r(record["reference"][:-1]): raise osv.except_osv( _("Error!"), _("Recursive mod10 is invalid for reference: %s.") % record["reference"] ) if line[2] == "5": record["amount"] *= -1 record["cost"] *= -1 total_amount += record["amount"] total_cost += record["cost"] records.append(record) account_receivable = False account_payable = False statement = statement_obj.browse(cursor, user, statement_id, context=context) for record in records: # Remove the 11 first char because it can be adherent number # TODO check if 11 is the right number reference = record["reference"][11:-1].lstrip("0") values = { "name": "IN " + reference, "date": record["date"], "amount": record["amount"], "ref": reference, "type": (record["amount"] >= 0 and "customer") or "supplier", "statement_id": statement_id, } line_ids = move_line_obj.search( cursor, user, [ ("ref", "like", reference), ("reconcile_id", "=", False), ("account_id.type", "in", ["receivable", "payable"]), ], order="date desc", context=context, ) if not line_ids: line_ids = _reconstruct_invoice_ref(cursor, user, reference, None) partner_id = False account_id = False for line in move_line_obj.browse(cursor, user, line_ids, context=context): account_receivable = line.partner_id.property_account_receivable.id account_payable = line.partner_id.property_account_payable.id partner_id = line.partner_id.id move_id = line.move_id.id if record["amount"] >= 0: if round(record["amount"] - line.debit, 2) < 0.01: # line2reconcile = line.id account_id = line.account_id.id break else: if round(line.credit + record["amount"], 2) < 0.01: # line2reconcile = line.id account_id = line.account_id.id break result = voucher_obj.onchange_partner_id( cursor, user, [], partner_id, journal_id=statement.journal_id.id, amount=abs(record["amount"]), currency_id=statement.currency.id, ttype="receipt", date=statement.date, context=context, ) voucher_res = { "type": "receipt", "name": values["name"], "partner_id": partner_id, "journal_id": statement.journal_id.id, "account_id": result.get("account_id", statement.journal_id.default_credit_account_id.id), "company_id": statement.company_id.id, "currency_id": statement.currency.id, "date": record["date"] or time.strftime("%Y-%m-%d"), "amount": abs(record["amount"]), "period_id": statement.period_id.id, } voucher_id = voucher_obj.create(cursor, user, voucher_res, context=context) context.update({"move_line_ids": line_ids}) values["voucher_id"] = voucher_id voucher_line_dict = False if result["value"]["line_ids"]: for line_dict in result["value"]["line_ids"]: move_line = move_line_obj.browse(cursor, user, line_dict["move_line_id"], context) if move_id == move_line.move_id.id: voucher_line_dict = line_dict if voucher_line_dict: voucher_line_dict.update({"voucher_id": voucher_id}) voucher_line_obj.create(cursor, user, voucher_line_dict, context=context) if not account_id: if record["amount"] >= 0: account_id = account_receivable else: account_id = account_payable ##If line not linked to an invoice we create a line not linked to a voucher if not account_id and not line_ids: name = "property_account_receivable" if record["amount"] < 0: name = "property_account_payable" prop = property_obj.search( cursor, user, [("name", "=", name), ("company_id", "=", statement.company_id.id), ("res_id", "=", False)], ) if prop: value = property_obj.read(cursor, user, prop[0], ["value_reference"]).get("value_reference", False) if value: account_id = int(value.split(",")[1]) else: raise osv.except_osv( _("Error!"), _("The properties account payable and account receivable are not set.") ) if not account_id and line_ids: raise osv.except_osv(_("Error!"), _("The properties account payable and account receivable are not set.")) values["account_id"] = account_id values["partner_id"] = partner_id statement_line_obj.create(cursor, user, values, context=context) attachment_obj.create( cursor, user, { "name": "BVR %s" % time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()), "datas": file, "datas_fname": "BVR %s.txt" % time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()), "res_model": "account.bank.statement", "res_id": statement_id, }, context=context, ) return {}
def _import(self, cursor, user, data, context=None): statement_line_obj = self.pool.get('account.bank.statement.line') # statement_reconcile_obj = pool.get('account.bank.statement.reconcile') voucher_obj = self.pool.get('account.voucher') voucher_line_obj = self.pool.get('account.voucher.line') move_line_obj = self.pool.get('account.move.line') property_obj = self.pool.get('ir.property') model_fields_obj = self.pool.get('ir.model.fields') attachment_obj = self.pool.get('ir.attachment') statement_obj = self.pool.get('account.bank.statement') property_obj = self.pool.get('ir.property') file = data['form']['file'] statement_id = data['id'] records = [] total_amount = 0 total_cost = 0 find_total = False if context is None: context = {} for lines in base64.decodestring(file).split("\n"): # Manage files without carriage return while lines: (line, lines) = (lines[:128], lines[128:]) record = {} if line[0:3] in ('999', '995'): if find_total: raise osv.except_osv(_('Error'), _('Too much total record found!')) find_total = True if lines: raise osv.except_osv(_('Error'), _('Record found after total record!')) amount = float(line[39:49]) + (float(line[49:51]) / 100) cost = float(line[69:76]) + (float(line[76:78]) / 100) if line[2] == '5': amount *= -1 cost *= -1 if round(amount - total_amount, 2) >= 0.01 \ or round(cost - total_cost, 2) >= 0.01: raise osv.except_osv(_('Error'), _('Total record different from the computed!')) if int(line[51:63]) != len(records): raise osv.except_osv(_('Error'), _('Number record different from the computed!')) else: record = { 'reference': line[12:39], 'amount': float(line[39:47]) + (float(line[47:49]) / 100), 'date': time.strftime('%Y-%m-%d', time.strptime(line[65:71], '%y%m%d')), 'cost': float(line[96:98]) + (float(line[98:100]) / 100), } if record['reference'] != mod10r(record['reference'][:-1]): raise osv.except_osv(_('Error'), _('Recursive mod10 is invalid for reference: %s') % \ record['reference']) if line[2] == '5': record['amount'] *= -1 record['cost'] *= -1 total_amount += record['amount'] total_cost += record['cost'] records.append(record) account_receivable = False account_payable = False statement = statement_obj.browse(cursor, user, statement_id, context=context) for record in records: # Remove the 11 first char because it can be adherent number # TODO check if 11 is the right number reference = record['reference'][11:-1].lstrip('0') values = { 'name': 'IN '+ reference, 'date': record['date'], 'amount': record['amount'], 'ref': reference, 'type': (record['amount'] >= 0 and 'customer') or 'supplier', 'statement_id': statement_id, } line_ids = move_line_obj.search(cursor, user, [ ('ref', 'like', reference), ('reconcile_id', '=', False), ('account_id.type', 'in', ['receivable', 'payable']), ], order='date desc', context=context) if not line_ids: line_ids = _reconstruct_invoice_ref(cursor, user, reference, None) partner_id = False account_id = False for line in move_line_obj.browse(cursor, user, line_ids, context=context): account_receivable = line.partner_id.property_account_receivable.id account_payable = line.partner_id.property_account_payable.id partner_id = line.partner_id.id move_id = line.move_id.id if record['amount'] >= 0: if round(record['amount'] - line.debit, 2) < 0.01: # line2reconcile = line.id account_id = line.account_id.id break else: if round(line.credit + record['amount'], 2) < 0.01: # line2reconcile = line.id account_id = line.account_id.id break context.update({'move_line_ids': line_ids}) result = voucher_obj.onchange_partner_id(cursor, user, [], partner_id, journal_id=statement.journal_id.id, price=abs(record['amount']), currency_id= statement.currency.id, ttype='receipt', date=statement.date ,context=context) voucher_res = { 'type': 'receipt' , 'name': values['name'], 'partner_id': partner_id, 'journal_id': statement.journal_id.id, 'account_id': result.get('account_id', statement.journal_id.default_credit_account_id.id), 'company_id': statement.company_id.id, 'currency_id': statement.currency.id, 'date': record['date'] or time.strftime('%Y-%m-%d'), 'amount': abs(record['amount']), 'period_id': statement.period_id.id } voucher_id = voucher_obj.create(cursor, user, voucher_res, context=context) values['voucher_id'] = voucher_id voucher_line_dict = False if result['value']['line_ids']: for line_dict in result['value']['line_ids']: move_line = move_line_obj.browse(cursor, user, line_dict['move_line_id'], context) if move_id == move_line.move_id.id: voucher_line_dict = line_dict if voucher_line_dict: voucher_line_dict.update({'voucher_id':voucher_id}) voucher_line_obj.create(cursor, user, voucher_line_dict, context=context) if not account_id: if record['amount'] >= 0: account_id = account_receivable else: account_id = account_payable ##If line not linked to an invoice we create a line not linked to a voucher if not account_id and not line_ids: name = "property_account_receivable" if record['amount'] < 0: name = "property_account_payable" prop = property_obj.search( cursor, user, [ ('name','=','property_account_receivable'), ('company_id','=',statement.company_id.id), ('res_id', '=', False) ] ) if prop: value = property_obj.read(cursor, user, prop[0], ['value_reference']).get('value_reference', False) if value : account_id = int(value.split(',')[1]) else : raise osv.except_osv(_('Error'), _('The properties account payable account receivable are not set')) if not account_id and line_ids: raise osv.except_osv(_('Error'), _('The properties account payable account receivable are not set')) values['account_id'] = account_id values['partner_id'] = partner_id statement_line_obj.create(cursor, user, values, context=context) attachment_obj.create(cursor, user, { 'name': 'BVR', 'datas': file, 'datas_fname': 'BVR.txt', 'res_model': 'account.bank.statement', 'res_id': statement_id, }, context=context) return {}