diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py index f24536ab59f..cc11c72cf06 100644 --- a/addons/l10n_be_coda/l10n_be_coda.py +++ b/addons/l10n_be_coda/l10n_be_coda.py @@ -2,9 +2,9 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# +# # Copyright (c) 2012 Noviat nv/sa (www.noviat.be). All rights reserved. -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the @@ -26,12 +26,13 @@ from tools.translate import _ import logging _logger = logging.getLogger(__name__) + class coda_bank_account(osv.osv): - _name= 'coda.bank.account' - _description= 'CODA Bank Account Configuration' + _name = 'coda.bank.account' + _description = 'CODA Bank Account Configuration' def _check_account_pain(self, cr, uid, context=None): - res = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', 'account_pain'), ('state','=','installed')]) + res = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', 'account_pain'), ('state', '=', 'installed')]) return res and True or False def _check_currency(self, cr, uid, ids, context=None): @@ -45,7 +46,7 @@ class coda_bank_account(osv.osv): _columns = { 'name': fields.char('Name', size=64, required=True), - 'bank_id': fields.many2one('res.partner.bank', 'Bank Account', required=True, + 'bank_id': fields.many2one('res.partner.bank', 'Bank Account', required=True, help='Bank Account Number.\nThe CODA import function will find its CODA processing parameters on this number.'), 'description1': fields.char('Primary Account Description', size=35, help='The Primary or Secondary Account Description should match the corresponding Account Description in the CODA file.'), @@ -53,15 +54,15 @@ class coda_bank_account(osv.osv): help='The Primary or Secondary Account Description should match the corresponding Account Description in the CODA file.'), 'state': fields.selection([ ('normal', 'Normal'), - ('info', 'Info')], + ('info', 'Info')], 'Type', required=True, select=1, help='No Bank Statements will be generated for CODA Bank Statements from Bank Accounts of type \'Info\'.'), - 'journal': fields.many2one('account.journal', 'Journal', - domain=[('type', '=', 'bank')], - states={'normal':[('required',True)],'info':[('required',False)]}, + 'journal': fields.many2one('account.journal', 'Journal', + domain=[('type', '=', 'bank')], + states={'normal': [('required', True)], 'info': [('required', False)]}, help='Bank Journal for the Bank Statement'), 'currency': fields.many2one('res.currency', 'Currency', required=True, - help='The currency of the CODA Bank Statement'), + help='The currency of the CODA Bank Statement'), 'coda_st_naming': fields.char('Bank Statement Naming Policy', size=64, help="Define the rules to create the name of the Bank Statements generated by the CODA processing." \ "\nE.g. %(code)s%(y)s/%(paper)s" \ @@ -73,14 +74,14 @@ class coda_bank_account(osv.osv): "\nPaper Statement sequence number (as specified on 'Old Balance' record): %(paper_ob)s" \ "\nPaper Statement sequence number (as specified on 'New Balance' record): %(paper)s"), 'awaiting_account': fields.many2one('account.account', 'Default Account for Unrecognized Movement', domain=[('type', '!=', 'view')], required=True, - help= 'Set here the default account that will be used if the partner cannot be unambiguously identified.'), + help='Set here the default account that will be used if the partner cannot be unambiguously identified.'), 'transfer_account': fields.many2one('account.account', 'Default Internal Transfer Account', domain=[('code', 'like', '58%'), ('type', '!=', 'view')], required=True, - help= 'Set here the default account that will be used for internal transfer between own bank accounts (e.g. transfer between current and deposit bank accounts).'), + help='Set here the default account that will be used for internal transfer between own bank accounts (e.g. transfer between current and deposit bank accounts).'), 'account_mapping_ids': fields.one2many('coda.account.mapping.rule', 'coda_bank_account_id', 'Account Mapping Rules'), - 'find_payment': fields.boolean('Lookup Payment Reference', + 'find_payment': fields.boolean('Lookup Payment Reference', help='Invoice lookup and reconciliation via the SEPA EndToEndReference.' \ '\nInstall the \'account_pain\' module if you want to take advantage of this feature.'), - 'find_bbacom': fields.boolean('Lookup Structured Communication of type \'BBA\'', + 'find_bbacom': fields.boolean('Lookup Structured Communication of type \'BBA\'', help='Partner lookup and reconciliation via the \'BBA\' Structured Communication.' \ '\nA partial reconciliation will be created when there is no exact match between the Invoice and Bank Transaction amounts.'), 'find_inv_number': fields.boolean('Lookup Invoice Number', @@ -93,22 +94,22 @@ class coda_bank_account(osv.osv): 'balance_start_enforce': fields.boolean('Prevent invalid Opening Balances', help="Do not process Statements with an Opening Balance that doesn't match the previous Closing Balance."), 'discard_dup': fields.boolean('Discard Duplicates', - help="Duplicate Bank Statements will be discarded. Select the corresponding 'CODA Bank Statement' in order to view the contents of such duplicates."), + help="Duplicate Bank Statements will be discarded. Select the corresponding 'CODA Bank Statement' in order to view the contents of such duplicates."), 'active': fields.boolean('Active', help='If the active field is set to False, it will allow you to hide the Bank Account without removing it.'), 'company_id': fields.many2one('res.company', 'Company', required=True), } _defaults = { - 'currency': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id, + 'currency': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id, 'state': 'normal', 'coda_st_naming': '%(code)s/%(y)s/%(coda)s', - 'active': True, + 'active': True, 'find_payment': _check_account_pain, 'find_bbacom': True, - 'find_inv_number': True, - 'find_partner': True, - 'update_partner': True, + 'find_inv_number': True, + 'find_partner': True, + 'update_partner': True, 'balance_start_enforce': True, - 'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id, + 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id, } _sql_constraints = [ ('account_uniq_1', 'unique (bank_id, description1, currency)', 'The combination of Bank Account, Account Description and Currency must be unique !'), @@ -133,42 +134,41 @@ class coda_bank_account(osv.osv): if not default: default = {} default = default.copy() - default.update({'journal_id': None}) + default.update({'journal_id': None}) default['description1'] = cba['description1'] or '' default['description2'] = cba['description2'] or '' default['name'] = (cba['name'] or '') + ' (copy)' - default['state'] = cba['state'] - return super(coda_bank_account, self).copy(cr, uid, id, default, context) + default['state'] = cba['state'] + return super(coda_bank_account, self).copy(cr, uid, id, default, context) def onchange_state(self, cr, uid, ids, state): - return state =='info' and {'value': {'journal': None}} or {} + return state == 'info' and {'value': {'journal': None}} or {} coda_bank_account() - class account_coda(osv.osv): _name = 'account.coda' _description = 'Object to store CODA Data Files' _order = 'coda_creation_date desc' _columns = { - 'name': fields.char('CODA Filename',size=128, readonly=True), + 'name': fields.char('CODA Filename', size=128, readonly=True), 'coda_data': fields.binary('CODA File', readonly=True), - 'statement_ids': fields.one2many('coda.bank.statement','coda_id','Generated CODA Bank Statements', readonly=True), + 'statement_ids': fields.one2many('coda.bank.statement', 'coda_id', 'Generated CODA Bank Statements', readonly=True), 'note': fields.text('Import Log', readonly=True), 'coda_creation_date': fields.date('CODA Creation Date', readonly=True, select=True), 'date': fields.date('Import Date', readonly=True, select=True), - 'user_id': fields.many2one('res.users','User', readonly=True, select=True), + 'user_id': fields.many2one('res.users', 'User', readonly=True, select=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True) } _defaults = { 'date': fields.date.context_today, - 'user_id': lambda self,cr,uid,context: uid, - 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.coda', context=c), - } + 'user_id': lambda self, cr, uid, context: uid, + 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.coda', context=c), + } _sql_constraints = [ ('coda_uniq', 'unique (name, coda_creation_date)', 'This CODA has already been imported !') - ] + ] def unlink(self, cr, uid, ids, context=None): if context is None: @@ -177,22 +177,23 @@ class account_coda(osv.osv): coda_st_obj = self.pool.get('coda.bank.statement') bank_st_obj = self.pool.get('account.bank.statement') for coda in self.browse(cr, uid, ids, context=context): - for coda_statement in coda.statement_ids: + for coda_statement in coda.statement_ids: if not context.get('coda_statement_unlink', False): if coda_st_obj.exists(cr, uid, coda_statement.id, context=context): - coda_st_obj.unlink(cr, uid, [coda_statement.id], context=context) + coda_st_obj.unlink(cr, uid, [coda_statement.id], context=context) if not context.get('bank_statement_unlink', False): if coda_st_obj.exists(cr, uid, coda_statement.id, context=context) and (coda_statement.type == 'normal') and bank_st_obj.exists(cr, uid, coda_statement.statement_id.id, context=context): - bank_st_obj.unlink(cr, uid, [coda_statement.statement_id.id], context=context) + bank_st_obj.unlink(cr, uid, [coda_statement.statement_id.id], context=context) context.update({'coda_unlink': False}) return super(account_coda, self).unlink(cr, uid, ids, context=context) - + account_coda() -class account_coda_trans_type(osv.osv): + +class account_coda_trans_type(osv.osv): _name = 'account.coda.trans.type' _description = 'CODA transaction type' - _rec_name = 'type' + _rec_name = 'type' _columns = { 'type': fields.char('Transaction Type', size=1, required=True), 'parent_id': fields.many2one('account.coda.trans.type', 'Parent'), @@ -200,49 +201,53 @@ class account_coda_trans_type(osv.osv): } account_coda_trans_type() -class account_coda_trans_code(osv.osv): + +class account_coda_trans_code(osv.osv): _name = 'account.coda.trans.code' _description = 'CODA transaction code' - _rec_name = 'code' + _rec_name = 'code' _columns = { 'code': fields.char('Code', size=2, required=True, select=1), 'type': fields.selection([ ('code', 'Transaction Code'), - ('family', 'Transaction Family')], - 'Type', required=True, select=1), + ('family', 'Transaction Family')], + 'Type', required=True, select=1), 'parent_id': fields.many2one('account.coda.trans.code', 'Family', select=1), 'description': fields.char('Description', size=128, translate=True, select=2), 'comment': fields.text('Comment', translate=True), } account_coda_trans_code() -class account_coda_trans_category(osv.osv): + +class account_coda_trans_category(osv.osv): _name = 'account.coda.trans.category' _description = 'CODA transaction category' - _rec_name = 'category' + _rec_name = 'category' _columns = { 'category': fields.char('Transaction Category', size=3, required=True), 'description': fields.char('Description', size=256, translate=True), } account_coda_trans_category() -class account_coda_comm_type(osv.osv): + +class account_coda_comm_type(osv.osv): _name = 'account.coda.comm.type' _description = 'CODA structured communication type' - _rec_name = 'code' + _rec_name = 'code' _columns = { 'code': fields.char('Structured Communication Type', size=3, required=True, select=1), 'description': fields.char('Description', size=128, translate=True), } _sql_constraints = [ - ('code_uniq', 'unique (code)','The Structured Communication Code must be unique !') + ('code_uniq', 'unique (code)', 'The Structured Communication Code must be unique !') ] account_coda_comm_type() + class coda_bank_statement(osv.osv): - _name = 'coda.bank.statement' - _description = 'CODA Bank Statement' - + _name = 'coda.bank.statement' + _description = 'CODA Bank Statement' + def _default_journal_id(self, cr, uid, context={}): if context.get('journal_id', False): return context['journal_id'] @@ -276,16 +281,16 @@ class coda_bank_statement(osv.osv): 'coda_id': fields.many2one('account.coda', 'CODA Data File', ondelete='cascade'), 'type': fields.selection([ ('normal', 'Normal'), - ('info', 'Info')], + ('info', 'Info')], 'Type', required=True, readonly=True, help='No Bank Statements are associated with CODA Bank Statements of type \'Info\'.'), - 'statement_id': fields.many2one('account.bank.statement', 'Associated Bank Statement'), + 'statement_id': fields.many2one('account.bank.statement', 'Associated Bank Statement'), 'journal_id': fields.many2one('account.journal', 'Journal', readonly=True, domain=[('type', '=', 'bank')]), - 'coda_bank_account_id': fields.many2one('coda.bank.account', 'Bank Account', readonly=True), + 'coda_bank_account_id': fields.many2one('coda.bank.account', 'Bank Account', readonly=True), 'period_id': fields.many2one('account.period', 'Period', required=True, readonly=True), 'balance_start': fields.float('Starting Balance', digits_compute=dp.get_precision('Account'), readonly=True), 'balance_end_real': fields.float('Ending Balance', digits_compute=dp.get_precision('Account'), readonly=True), - 'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance'), + 'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance'), 'line_ids': fields.one2many('coda.bank.statement.line', 'statement_id', 'CODA Bank Statement lines', readonly=True), 'currency': fields.many2one('res.currency', 'Currency', required=True, readonly=True, @@ -293,14 +298,14 @@ class coda_bank_statement(osv.osv): 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), } _defaults = { - 'type': 'normal', - 'currency': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id, + 'type': 'normal', + 'currency': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id, 'journal_id': _default_journal_id, 'period_id': _get_period, } def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): - if context is None: + if context is None: context = {} res = super(coda_bank_statement, self).search(cr, uid, args=args, offset=offset, limit=limit, order=order, context=context, count=count) @@ -314,16 +319,16 @@ class coda_bank_statement(osv.osv): context.update({'coda_statement_unlink': True}) coda_obj = self.pool.get('account.coda') bank_st_obj = self.pool.get('account.bank.statement') - + # find all CODA bank statements that are associated with the selected CODA bank statements via a common CODA file - new_ids = [] + new_ids = [] for coda_statement in self.browse(cr, uid, ids, context=context): if coda_obj.exists(cr, uid, coda_statement.coda_id.id, context=context): new_ids += [x.id for x in coda_obj.browse(cr, uid, coda_statement.coda_id.id, context=context).statement_ids] - # unlink CODA banks statements as well as associated bank statements and CODA files + # unlink CODA banks statements as well as associated bank statements and CODA files for coda_statement in self.browse(cr, uid, new_ids, context=context): - if coda_statement.statement_id.state == 'confirm': + if coda_statement.statement_id.state == 'confirm': raise osv.except_osv(_('Invalid action !'), _("Cannot delete CODA Bank Statement '%s' of Journal '%s'." \ "\nThe associated Bank Statement has already been confirmed !" \ @@ -335,13 +340,14 @@ class coda_bank_statement(osv.osv): coda_obj.unlink(cr, uid, [coda_statement.coda_id.id], context=context) if not context.get('bank_statement_unlink', False): if coda_statement.statement_id and bank_st_obj.exists(cr, uid, coda_statement.statement_id.id, context=context): - bank_st_obj.unlink(cr, uid, [coda_statement.statement_id.id], context=context) + bank_st_obj.unlink(cr, uid, [coda_statement.statement_id.id], context=context) context.update({'coda_statement_unlink': False}) return super(coda_bank_statement, self).unlink(cr, uid, new_ids, context=context) - + coda_bank_statement() + class account_bank_statement(osv.osv): _inherit = 'account.bank.statement' _columns = { @@ -350,7 +356,7 @@ class account_bank_statement(osv.osv): # _sql_constraints = [ # ('name_company_uniq', 'unique (name,company_id)', 'The name of the Bank Statement must be unique per company !') # ] - + def unlink(self, cr, uid, ids, context=None): if context is None: context = {} @@ -359,15 +365,15 @@ class account_bank_statement(osv.osv): coda_st_obj = self.pool.get('coda.bank.statement') # find all statements that are associated with the selected bank statements via a common CODA file - ids_plus = [] + ids_plus = [] for statement in self.browse(cr, uid, ids, context=context): if statement.coda_statement_id: for x in coda_obj.browse(cr, uid, statement.coda_statement_id.coda_id.id, context=context).statement_ids: if x.type == 'normal': ids_plus += [x.statement_id.id] - + # unlink banks statements as well as associated CODA bank statements and CODA files - for statement in self.browse(cr, uid, ids_plus, context=context): + for statement in self.browse(cr, uid, ids_plus, context=context): if not context.get('coda_statement_unlink', False): if statement.coda_statement_id and coda_st_obj.exists(cr, uid, statement.coda_statement_id.id, context=context): coda_st_obj.unlink(cr, uid, [statement.coda_statement_id.id], context=context) @@ -381,52 +387,54 @@ class account_bank_statement(osv.osv): context.update({'bank_statement_unlink': False}) new_ids = list(set(ids + ids_plus)) return super(account_bank_statement, self).unlink(cr, uid, new_ids, context=context) - + account_bank_statement() + class coda_bank_statement_line(osv.osv): - _name = 'coda.bank.statement.line' - _order = 'sequence' + _name = 'coda.bank.statement.line' + _order = 'sequence' _description = 'CODA Bank Statement Line' _columns = { 'name': fields.char('Communication', size=268, required=True), 'sequence': fields.integer('Sequence'), 'date': fields.date('Entry Date', required=True), - 'val_date': fields.date('Valuta Date'), - 'account_id': fields.many2one('account.account','Account'), + 'val_date': fields.date('Valuta Date'), + 'account_id': fields.many2one('account.account', 'Account'), 'type': fields.selection([ - ('supplier','Supplier'), - ('customer','Customer'), - ('general','General'), - ('globalisation','Globalisation'), - ('information','Information'), - ('communication','Free Communication'), + ('supplier', 'Supplier'), + ('customer', 'Customer'), + ('general', 'General'), + ('globalisation', 'Globalisation'), + ('information', 'Information'), + ('communication', 'Free Communication'), ], 'Type', required=True), - 'globalisation_level': fields.integer('Globalisation Level', + 'globalisation_level': fields.integer('Globalisation Level', help="The value which is mentioned (1 to 9), specifies the hierarchy level" " of the globalisation of which this record is the first." "\nThe same code will be repeated at the end of the globalisation."), - 'globalisation_amount': fields.float('Globalisation Amount', digits_compute=dp.get_precision('Account')), + 'globalisation_amount': fields.float('Globalisation Amount', digits_compute=dp.get_precision('Account')), 'globalisation_id': fields.many2one('account.bank.statement.line.global', 'Globalisation ID', readonly=True, - help="Code to identify transactions belonging to the same globalisation level within a batch payment"), + help="Code to identify transactions belonging to the same globalisation level within a batch payment"), 'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')), 'partner_id': fields.many2one('res.partner', 'Partner'), 'counterparty_name': fields.char('Counterparty Name', size=35), - 'counterparty_bic': fields.char('Counterparty BIC', size=11), - 'counterparty_number': fields.char('Counterparty Number', size=34), - 'counterparty_currency': fields.char('Counterparty Currency', size=3), + 'counterparty_bic': fields.char('Counterparty BIC', size=11), + 'counterparty_number': fields.char('Counterparty Number', size=34), + 'counterparty_currency': fields.char('Counterparty Currency', size=3), 'payment_reference': fields.char('Payment Reference', size=35, help="Payment Reference. For SEPA (SCT or SDD) transactions, the PaymentInformationIdentification "\ "is recorded in this field pertaining to a globalisation, and the EndToEndReference for " \ - "simple transactions or for the details of a globalisation."), + "simple transactions or for the details of a globalisation."), 'statement_id': fields.many2one('coda.bank.statement', 'CODA Bank Statement', select=True, required=True, ondelete='cascade'), 'coda_bank_account_id': fields.related('statement_id', 'coda_bank_account_id', type='many2one', relation='coda.bank.account', string='Bank Account', store=True, readonly=True), 'ref': fields.char('Reference', size=32), 'note': fields.text('Notes'), - 'company_id': fields.related('statement_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), + 'company_id': fields.related('statement_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), } + #TODO : Check this function. account_bank_statement_line Seems undefined : ) def unlink(self, cr, uid, ids, context=None): if context is None: context = {} @@ -434,7 +442,8 @@ class coda_bank_statement_line(osv.osv): raise osv.except_osv('Warning', _('Delete operation not allowed !')) return super(account_bank_statement_line, self).unlink(cr, uid, ids, context=context) -coda_bank_statement_line() +coda_bank_statement_line() + class account_bank_statement_line_global(osv.osv): _inherit = 'account.bank.statement.line.global' @@ -443,6 +452,7 @@ class account_bank_statement_line_global(osv.osv): } account_bank_statement_line_global() + class coda_account_mapping_rule(osv.osv): _name = 'coda.account.mapping.rule' _description = 'Rules Engine to assign accounts during CODA parsing' @@ -450,7 +460,7 @@ class coda_account_mapping_rule(osv.osv): _columns = { 'coda_bank_account_id': fields.many2one('coda.bank.account', 'CODA Bank Account', ondelete='cascade'), 'sequence': fields.integer('Sequence', help='Determines the order of the rules to assign accounts'), - 'name': fields.char('Rule Name', size=128, required=True), + 'name': fields.char('Rule Name', size=128, required=True), # matching criteria 'trans_type_id': fields.many2one('account.coda.trans.type', 'Transaction Type'), 'trans_family_id': fields.many2one('account.coda.trans.code', 'Transaction Family', domain=[('type', '=', 'family')]), @@ -465,18 +475,18 @@ class coda_account_mapping_rule(osv.osv): _defaults = { 'active': True, } - - def account_id_get(self, cr, uid, coda_bank_account_id, trans_type_id=None, trans_family_id=None, - trans_code_id=None, trans_category_id=None, struct_comm_type_id=None, partner_id=None, context=None): + + def account_id_get(self, cr, uid, coda_bank_account_id, trans_type_id=None, trans_family_id=None, + trans_code_id=None, trans_category_id=None, struct_comm_type_id=None, partner_id=None, context=None): cr.execute('SELECT account_id, trans_type_id, trans_family_id, trans_code_id, trans_category_id, struct_comm_type_id, partner_id ' \ 'FROM coda_account_mapping_rule ' \ 'WHERE active = TRUE AND coda_bank_account_id = %s ' \ 'ORDER BY sequence' % coda_bank_account_id ) - rules = cr.fetchall() + rules = cr.fetchall() condition = '(not rule[1] or (trans_type_id == rule[1])) and (not rule[2] or (trans_family_id == rule[2])) ' \ 'and (not rule[3] or (trans_code_id == rule[3])) and (not rule[4] or (trans_category_id == rule[4])) ' \ - 'and (not rule[5] or (struct_comm_type_id == rule[5])) and (not rule[6] or (partner_id == rule[6]))' + 'and (not rule[5] or (struct_comm_type_id == rule[5])) and (not rule[6] or (partner_id == rule[6]))' account_id = None for rule in rules: if eval(condition): diff --git a/addons/l10n_be_coda/res_bank.py b/addons/l10n_be_coda/res_bank.py index 6a3581539e9..47e7fdf8569 100755 --- a/addons/l10n_be_coda/res_bank.py +++ b/addons/l10n_be_coda/res_bank.py @@ -2,9 +2,9 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# +# # Copyright (c) 2012 Noviat nv/sa (www.noviat.be). All rights reserved. -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the @@ -22,6 +22,7 @@ from osv import fields, osv + class res_bank(osv.osv): _inherit = 'res.bank' _columns = { diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py index 6f055ca3d92..ea7558e13da 100644 --- a/addons/l10n_be_coda/wizard/account_coda_import.py +++ b/addons/l10n_be_coda/wizard/account_coda_import.py @@ -2,9 +2,9 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# +# # Copyright (c) 2012 Noviat nv/sa (www.noviat.be). All rights reserved. -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the @@ -22,7 +22,7 @@ import time import base64 -from osv import fields,osv +from osv import fields, osv from tools.translate import _ import netsvc import re @@ -31,20 +31,21 @@ from sys import exc_info import logging _logger = logging.getLogger(__name__) + class account_coda_import(osv.osv_memory): _name = 'account.coda.import' _description = 'Import CODA File' _columns = { 'coda_data': fields.binary('CODA File', required=True), 'coda_fname': fields.char('CODA Filename', size=128, required=True), - 'note':fields.text('Log'), + 'note': fields.text('Log'), } _defaults = { 'coda_fname': lambda *a: '', } def _check_account_payment(self, cr, uid, context=None): - res = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', 'account_payment'), ('state','=','installed')]) + res = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', 'account_payment'), ('state', '=', 'installed')]) return res and True or False def coda_parsing(self, cr, uid, ids, context=None, batch=False, codafile=None, codafilename=None): @@ -54,15 +55,15 @@ class account_coda_import(osv.osv_memory): codafile = str(codafile) codafilename = codafilename else: - data=self.browse(cr,uid,ids)[0] + data = self.browse(cr, uid, ids)[0] try: codafile = data.coda_data - codafilename = data.coda_fname + codafilename = data.coda_fname except: raise osv.except_osv(_('Error!'), _('Wizard in incorrect state. Please hit the Cancel button!')) return {} - currency_obj = self.pool.get('res.currency') + currency_obj = self.pool.get('res.currency') coda_bank_account_obj = self.pool.get('coda.bank.account') trans_type_obj = self.pool.get('account.coda.trans.type') trans_code_obj = self.pool.get('account.coda.trans.code') @@ -78,29 +79,25 @@ class account_coda_import(osv.osv_memory): bank_st_line_obj = self.pool.get('account.bank.statement.line') glob_obj = self.pool.get('account.bank.statement.line.global') inv_obj = self.pool.get('account.invoice') - move_obj = self.pool.get('account.move') move_line_obj = self.pool.get('account.move.line') voucher_obj = self.pool.get('account.voucher') - voucher_line_obj = self.pool.get('account.voucher.line') seq_obj = self.pool.get('ir.sequence') mod_obj = self.pool.get('ir.model.data') - partner_obj = self.pool.get('res.partner') account_mapping_obj = self.pool.get('coda.account.mapping.rule') - + if self._check_account_payment(cr, uid): payment_line_obj = self.pool.get('payment.line') else: payment_line_obj = False - + wf_service = netsvc.LocalService('workflow') - be_country_id = self.pool.get('res.country').search(cr, uid, [('code', '=', 'BE')])[0] coda_bank_table = coda_bank_account_obj.read(cr, uid, coda_bank_account_obj.search(cr, uid, []), context=context) for coda_bank in coda_bank_table: coda_bank.update({'journal_code': coda_bank['journal'] and journal_obj.browse(cr, uid, coda_bank['journal'][0], context=context).code or ''}) coda_bank.update({'iban': partner_bank_obj.browse(cr, uid, coda_bank['bank_id'][0], context=context).iban}) coda_bank.update({'acc_number': partner_bank_obj.browse(cr, uid, coda_bank['bank_id'][0], context=context).acc_number}) - coda_bank.update({'currency_name': currency_obj.browse(cr, uid, coda_bank['currency'][0], context=context).name}) + coda_bank.update({'currency_name': currency_obj.browse(cr, uid, coda_bank['currency'][0], context=context).name}) trans_type_table = trans_type_obj.read(cr, uid, trans_type_obj.search(cr, uid, []), context=context) trans_code_table = trans_code_obj.read(cr, uid, trans_code_obj.search(cr, uid, []), context=context) trans_category_table = trans_category_obj.read(cr, uid, trans_category_obj.search(cr, uid, []), context=context) @@ -112,9 +109,9 @@ class account_coda_import(osv.osv_memory): coda_statements = [] recordlist = unicode(base64.decodestring(codafile), 'windows-1252', 'strict').split('\n') digits = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account') - + for line in recordlist: - + if not line: pass elif line[0] == '0': @@ -124,10 +121,10 @@ class account_coda_import(osv.osv_memory): coda_statement_lines = {} st_line_seq = 0 # header data - coda_statement['currency'] = 'EUR' # default currency + coda_statement['currency'] = 'EUR' # default currency coda_statement['version'] = line[127] coda_version = line[127] - if coda_version not in ['1','2']: + if coda_version not in ['1', '2']: err_string = _('\nCODA V%s statements are not supported, please contact your bank!') % coda_version err_code = 'R0001' if batch: @@ -137,10 +134,10 @@ class account_coda_import(osv.osv_memory): coda_statement['date'] = str2date(line[5:11]) coda_statement['coda_creation_date'] = str2date(line[5:11]) coda_statement['separate_application'] = line[83:88] - coda_statement['first_transaction_date'] = False + coda_statement['first_transaction_date'] = False coda_statement['state'] = 'draft' - - coda_id = coda_obj.search(cr, uid,[ + + coda_id = coda_obj.search(cr, uid, [ ('name', '=', codafilename), ('coda_creation_date', '=', coda_statement['date']), ]) @@ -151,7 +148,7 @@ class account_coda_import(osv.osv_memory): if batch: return (err_code, err_string) raise osv.except_osv(_('Warning !'), err_string) - + elif line[0] == '1': if coda_version == '1': coda_statement['acc_number'] = line[5:17] @@ -159,7 +156,7 @@ class account_coda_import(osv.osv_memory): coda_statement['currency'] = line[18:21] elif line[1] == '0': # Belgian bank account BBAN structure coda_statement['acc_number'] = line[5:17] - coda_statement['currency'] = line[18:21] + coda_statement['currency'] = line[18:21] elif line[1] == '1': # foreign bank account BBAN structure err_string = _('\nForeign bank accounts with BBAN structure are not supported !') err_code = 'R1001' @@ -167,7 +164,7 @@ class account_coda_import(osv.osv_memory): return (err_code, err_string) raise osv.except_osv(_('Data Error!'), err_string) elif line[1] == '2': # Belgian bank account IBAN structure - coda_statement['acc_number']=line[5:21] + coda_statement['acc_number'] = line[5:21] coda_statement['currency'] = line[39:42] elif line[1] == '3': # foreign bank account IBAN structure err_string = _('\nForeign bank accounts with IBAN structure are not supported !') @@ -184,22 +181,22 @@ class account_coda_import(osv.osv_memory): coda_statement['description'] = line[90:125].strip() cba_filter = lambda x: (coda_statement['acc_number'] in _get_acc_numbers(x['acc_number'])) \ and (coda_statement['currency'] == x['currency_name']) and (coda_statement['description'] in [x['description1'] or '', x['description2'] or '']) - coda_bank = filter(cba_filter, coda_bank_table) + coda_bank = filter(cba_filter, coda_bank_table) if coda_bank: - coda_bank = coda_bank[0] + coda_bank = coda_bank[0] coda_statement['type'] = coda_bank['state'] coda_statement['journal_id'] = coda_bank['journal'] and coda_bank['journal'][0] coda_statement['currency_id'] = coda_bank['currency'][0] - coda_statement['coda_bank_account_id'] = coda_bank['id'] - coda_statement['account_mapping_ids'] = coda_bank['account_mapping_ids'] - coda_statement['coda_bank_params'] = coda_bank + coda_statement['coda_bank_account_id'] = coda_bank['id'] + coda_statement['account_mapping_ids'] = coda_bank['account_mapping_ids'] + coda_statement['coda_bank_params'] = coda_bank awaiting_acc = coda_bank['awaiting_account'][0] transfer_acc = coda_bank['transfer_account'][0] find_payment = coda_bank['find_payment'] find_bbacom = coda_bank['find_bbacom'] - find_inv_number = coda_bank['find_inv_number'] + find_inv_number = coda_bank['find_inv_number'] find_partner = coda_bank['find_partner'] - update_partner = coda_bank['update_partner'] + update_partner = coda_bank['update_partner'] coda_statement['balance_start_enforce'] = coda_bank['balance_start_enforce'] coda_statement['discard_dup'] = coda_bank['discard_dup'] company_id = coda_bank['company_id'][0] @@ -217,7 +214,7 @@ class account_coda_import(osv.osv_memory): bal_start = list2float(line[43:58]) # old balance data if line[42] == '1': # 1= Debit bal_start = - bal_start - coda_statement['balance_start'] = bal_start + coda_statement['balance_start'] = bal_start coda_statement['old_balance_date'] = str2date(line[58:64]) coda_statement['acc_holder'] = line[64:90] coda_statement['paper_ob_seq_number'] = line[2:5] @@ -225,50 +222,50 @@ class account_coda_import(osv.osv_memory): elif line[0] == '2': # movement data record 2 - + if line[1] == '1': # movement data record 2.1 st_line = {} st_line_seq = st_line_seq + 1 st_line['sequence'] = st_line_seq st_line['type'] = 'general' - st_line['reconcile'] = False + st_line['reconcile'] = False st_line['trans_family'] = False st_line['struct_comm_type'] = '' st_line['struct_comm_type_id'] = 0 st_line['struct_comm_type_desc'] = '' st_line['struct_comm_bba'] = '' st_line['communication'] = '' - st_line['payment_reference'] = '' + st_line['payment_reference'] = '' st_line['partner_id'] = 0 st_line['account_id'] = 0 st_line['counterparty_name'] = '' - st_line['counterparty_bic'] = '' + st_line['counterparty_bic'] = '' st_line['counterparty_number'] = '' - st_line['counterparty_currency'] = '' + st_line['counterparty_currency'] = '' st_line['glob_lvl_flag'] = False st_line['globalisation_id'] = 0 st_line['globalisation_code'] = '' st_line['globalisation_amount'] = False st_line['amount'] = False - + st_line['ref'] = line[2:10] st_line['ref_move'] = line[2:6] st_line['ref_move_detail'] = line[6:10] - + if st_line_seq == 1: - main_move_stack = [st_line] # initialise main_move_stack (used to link 2.1 detail records to 2.1 main record - glob_lvl_stack = [0] # initialise globalisation stack + main_move_stack = [st_line] # initialise main_move_stack (used to link 2.1 detail records to 2.1 main record + glob_lvl_stack = [0] # initialise globalisation stack elif st_line['ref_move_detail'] == '0000': - glob_lvl_stack = [0] # re-initialise globalisation stack - + glob_lvl_stack = [0] # re-initialise globalisation stack + st_line['trans_ref'] = line[10:31] st_line_amt = list2float(line[32:47]) if line[31] == '1': # 1=debit st_line_amt = - st_line_amt - + st_line['trans_type'] = line[53] - trans_type = filter(lambda x: st_line['trans_type'] == x['type'], trans_type_table) + trans_type = filter(lambda x: st_line['trans_type'] == x['type'], trans_type_table) if not trans_type: err_string = _('\nThe File contains an invalid CODA Transaction Type : %s!') % st_line['trans_type'] err_code = 'R2001' @@ -276,13 +273,13 @@ class account_coda_import(osv.osv_memory): return (err_code, err_string) raise osv.except_osv(_('Data Error!'), err_string) st_line['trans_type_id'] = trans_type[0]['id'] - st_line['trans_type_desc'] = trans_type[0]['description'] - - # processing of amount depending on globalisation code + st_line['trans_type_desc'] = trans_type[0]['description'] + + # processing of amount depending on globalisation code glob_lvl_flag = int(line[124]) - if glob_lvl_flag > 0: - if glob_lvl_stack[-1] == glob_lvl_flag: - st_line['glob_lvl_flag'] = glob_lvl_flag + if glob_lvl_flag > 0: + if glob_lvl_stack[-1] == glob_lvl_flag: + st_line['glob_lvl_flag'] = glob_lvl_flag st_line['amount'] = st_line_amt glob_lvl_stack.pop() else: @@ -292,7 +289,7 @@ class account_coda_import(osv.osv_memory): st_line['globalisation_amount'] = st_line_amt else: st_line['amount'] = st_line_amt - + # The 'globalisation' concept can also be implemented without the globalisation level flag. # This is e.g. used by Europabank to give the details of Card Payments. if st_line['ref_move'] == main_move_stack[-1]['ref_move']: @@ -303,7 +300,7 @@ class account_coda_import(osv.osv_memory): if batch: return (err_code, err_string) raise osv.except_osv(_('Data Error!'), err_string) - elif st_line['ref_move_detail'] != '0000': + elif st_line['ref_move_detail'] != '0000': if glob_lvl_stack[-1] == 0: # promote associated move record into a globalisation glob_lvl_flag = 1 @@ -319,7 +316,7 @@ class account_coda_import(osv.osv_memory): 'account_id': 0, }) main_move_stack[-1]['promoted'] = True - if not main_move_stack[-1].get('detail_cnt'): + if not main_move_stack[-1].get('detail_cnt'): main_move_stack[-1]['detail_cnt'] = 1 else: main_move_stack[-1]['detail_cnt'] += 1 @@ -328,17 +325,17 @@ class account_coda_import(osv.osv_memory): st_line['val_date'] = str2date(line[47:53]) # positions 54-61 : transaction code st_line['trans_family'] = line[54:56] - trans_family = filter(lambda x: (x['type'] == 'family') and (st_line['trans_family'] == x['code']), trans_code_table) + trans_family = filter(lambda x: (x['type'] == 'family') and (st_line['trans_family'] == x['code']), trans_code_table) if not trans_family: - err_string = _('\nThe File contains an invalid CODA Transaction Family : %s!') % st_line['trans_family'] + err_string = _('\nThe File contains an invalid CODA Transaction Family : %s!') % st_line['trans_family'] err_code = 'R2002' if batch: return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) + raise osv.except_osv(_('Data Error!'), err_string) st_line['trans_family_id'] = trans_family[0]['id'] st_line['trans_family_desc'] = trans_family[0]['description'] st_line['trans_code'] = line[56:58] - trans_code = filter(lambda x: (x['type'] == 'code') and (st_line['trans_code'] == x['code']) and (trans_family[0]['id'] == x['parent_id'][0]), + trans_code = filter(lambda x: (x['type'] == 'code') and (st_line['trans_code'] == x['code']) and (trans_family[0]['id'] == x['parent_id'][0]), trans_code_table) if trans_code: st_line['trans_code_id'] = trans_code[0]['id'] @@ -347,17 +344,17 @@ class account_coda_import(osv.osv_memory): st_line['trans_code_id'] = None st_line['trans_code_desc'] = _('Transaction Code unknown, please consult your bank.') st_line['trans_category'] = line[58:61] - trans_category = filter(lambda x: st_line['trans_category'] == x['category'], trans_category_table) + trans_category = filter(lambda x: st_line['trans_category'] == x['category'], trans_category_table) if trans_category: st_line['trans_category_id'] = trans_category[0]['id'] st_line['trans_category_desc'] = trans_category[0]['description'] else: st_line['trans_category_id'] = None - st_line['trans_category_desc'] = _('Transaction Category unknown, please consult your bank.') - # positions 61-115 : communication + st_line['trans_category_desc'] = _('Transaction Category unknown, please consult your bank.') + # positions 61-115 : communication if line[61] == '1': st_line['struct_comm_type'] = line[62:65] - comm_type = filter(lambda x: st_line['struct_comm_type'] == x['code'], comm_type_table) + comm_type = filter(lambda x: st_line['struct_comm_type'] == x['code'], comm_type_table) if not comm_type: err_string = _('\nThe File contains an invalid Structured Communication Type : %s!') % st_line['struct_comm_type'] err_code = 'R2003' @@ -368,28 +365,28 @@ class account_coda_import(osv.osv_memory): st_line['struct_comm_type_desc'] = comm_type[0]['description'] st_line['communication'] = st_line['name'] = line[65:115] if st_line['struct_comm_type'] in ['101', '102']: - bbacomm = line[65:77] - st_line['struct_comm_bba'] = st_line['name'] = '+++' + bbacomm[0:3] + '/' + bbacomm[3:7] + '/' + bbacomm[7:] + '+++' + bbacomm = line[65:77] + st_line['struct_comm_bba'] = st_line['name'] = '+++' + bbacomm[0:3] + '/' + bbacomm[3:7] + '/' + bbacomm[7:] + '+++' else: st_line['communication'] = st_line['name'] = line[62:115] st_line['entry_date'] = str2date(line[115:121]) if st_line['sequence'] == 1: coda_statement['first_transaction_date'] = st_line['entry_date'] - # positions 122-124 not processed - coda_statement_lines[st_line_seq] = st_line # store transaction - + # positions 122-124 not processed + coda_statement_lines[st_line_seq] = st_line # store transaction + if st_line['ref_move'] != main_move_stack[-1]['ref_move']: if main_move_stack[-1].get('detail_cnt') and main_move_stack[-1].get('promoted'): # add closing globalisation level on previous detail record in order to correctly close # moves that have been 'promoted' to globalisation - closeglobalise = coda_statement['coda_statement_lines'][st_line_seq-1] + closeglobalise = coda_statement['coda_statement_lines'][st_line_seq - 1] closeglobalise.update({ 'glob_lvl_flag': main_move_stack[-1]['glob_lvl_flag'], }) else: # demote record with globalisation code from 'globalisation' to 'general' when no detail records # the same logic is repeated on the New Balance Record ('8 Record') in order to cope with CODA files - # containing a single 2.1 record that needs to be 'demoted'. + # containing a single 2.1 record that needs to be 'demoted'. if main_move_stack[-1]['type'] == 'globalisation' and not main_move_stack[-1].get('detail_cnt'): # demote record with globalisation code from 'globalisation' to 'general' when no detail records main_st_line_seq = main_move_stack[-1]['sequence'] @@ -403,7 +400,7 @@ class account_coda_import(osv.osv_memory): main_move_stack.pop() main_move_stack.append(st_line) coda_statement['coda_statement_lines'] = coda_statement_lines - + elif line[1] == '2': # movement data record 2.2 if coda_statement['coda_statement_lines'][st_line_seq]['ref'][0:4] != line[2:6]: @@ -412,12 +409,12 @@ class account_coda_import(osv.osv_memory): err_code = 'R2004' if batch: return (err_code, err_string) - raise osv.except_osv(_('Error!'), err_string) + raise osv.except_osv(_('Error!'), err_string) coda_statement['coda_statement_lines'][st_line_seq]['name'] += line[10:63] coda_statement['coda_statement_lines'][st_line_seq]['communication'] += line[10:63] coda_statement['coda_statement_lines'][st_line_seq]['payment_reference'] = line[63:98].strip() coda_statement['coda_statement_lines'][st_line_seq]['counterparty_bic'] = line[98:109].strip() - + elif line[1] == '3': # movement data record 2.3 if coda_statement['coda_statement_lines'][st_line_seq]['ref'][0:4] != line[2:6]: @@ -426,7 +423,7 @@ class account_coda_import(osv.osv_memory): err_code = 'R2005' if batch: return (err_code, err_string) - raise osv.except_osv(_('Error!'), err_string) + raise osv.except_osv(_('Error!'), err_string) st_line = coda_statement_lines[st_line_seq] if coda_version == '1': counterparty_number = line[10:22].strip() @@ -438,7 +435,7 @@ class account_coda_import(osv.osv_memory): counterparty_currency = line[23:26].strip() else: counterparty_number = line[10:44].strip() - counterparty_currency = line[44:47].strip() + counterparty_currency = line[44:47].strip() counterparty_name = line[47:82].strip() st_line['name'] += line[82:125] st_line['communication'] += line[82:125] @@ -447,20 +444,20 @@ class account_coda_import(osv.osv_memory): st_line['counterparty_name'] = counterparty_name """ TO DO: - + replace code infra by check on flag 128 and copy info in Notes Field. - + if counterparty_currency not in [coda_bank['currency_name'], '']: err_string = _('\nCODA parsing error on movement data record 2.3, seq nr %s!' \ - '\nPlease report this issue via your OpenERP support channel.') % line[2:10] + '\nPlease report this issue via your OpenERP support channel.') % line[2:10] err_code = 'R2006' if batch: return (err_code, err_string) - raise osv.except_osv(_('Error!'), err_string) + raise osv.except_osv(_('Error!'), err_string) """ - # invoice matching and reconciliation - if st_line['type'] == 'general': + # invoice matching and reconciliation + if st_line['type'] == 'general': match = False payment_reference_match = False inv_ids = None @@ -480,17 +477,17 @@ class account_coda_import(osv.osv_memory): st_line['reconcile'] = payline.move_line_id.id st_line['account_id'] = payline.move_line_id.account_id.id if payline._get_ml_inv_ref: - inv_type = payline.ml_inv_ref.type + inv_type = payline.ml_inv_ref.type st_line['type'] = inv_type == 'in_invoice' and 'supplier' or 'customer' else: st_line['type'] = 'general' else: err_string = _('\nThe CODA parsing detected a payment reference ambiguity while processing movement data record 2.3, seq nr %s!' \ - '\nPlease check your Payment Gateway configuration or contact your OpenERP support channel.') % line[2:10] + '\nPlease check your Payment Gateway configuration or contact your OpenERP support channel.') % line[2:10] err_code = 'R2007' if batch: return (err_code, err_string) - raise osv.except_osv(_('Error!'), err_string) + raise osv.except_osv(_('Error!'), err_string) # check bba scor in bank statement line against open invoices if st_line['struct_comm_bba'] and find_bbacom: @@ -498,15 +495,15 @@ class account_coda_import(osv.osv_memory): domain = [('type', 'in', ['out_invoice', 'in_refund'])] else: domain = [('type', 'in', ['in_invoice', 'out_refund'])] - inv_ids = inv_obj.search(cr , uid, - domain + [('state', '=', 'open'), ('reference' ,'=', st_line['struct_comm_bba']), ('reference_type' ,'=', 'bba')]) + inv_ids = inv_obj.search(cr, uid, + domain + [('state', '=', 'open'), ('reference', '=', st_line['struct_comm_bba']), ('reference_type', '=', 'bba')]) if not inv_ids: coda_parsing_note += _("\n Bank Statement '%%(name)s' line '%s':" \ "\n There is no invoice matching the Structured Communication '%s'!" \ "\n Please verify and adjust the invoice and perform the import again or otherwise change the corresponding entry manually in the generated Bank Statement.") \ % (st_line['ref'], st_line['struct_comm_bba']) elif len(inv_ids) == 1: - match = True + match = True elif len(inv_ids) > 1: coda_parsing_note += _("\n Bank Statement '%%(name)s' line '%s':" \ "\n There are multiple invoices matching the Structured Communication '%s'!" \ @@ -527,7 +524,7 @@ class account_coda_import(osv.osv_memory): else: select2 = " AND type IN ('in_invoice', 'out_refund')" cr.execute(select + select2) - res=cr.fetchall() + res = cr.fetchall() if res: inv_ids = [x[0] for x in res] if len(inv_ids) == 1: @@ -548,26 +545,26 @@ class account_coda_import(osv.osv_memory): if st_line['amount'] > 0: select2 = " AND type = 'out_invoice' AND free_comm ilike '%'||number||'%'" cr.execute(select + select2) - res=cr.fetchall() + res = cr.fetchall() if res: inv_ids = [x[0] for x in res] - else: + else: select2 = " AND type = 'in_refund' AND free_comm ilike '%'||reference||'%'" cr.execute(select + select2) - res=cr.fetchall() + res = cr.fetchall() if res: inv_ids = [x[0] for x in res] # 'in_invoice', 'out_refund' else: select2 = " AND type = 'in_invoice' AND free_comm ilike '%'||reference||'%'" cr.execute(select + select2) - res=cr.fetchall() + res = cr.fetchall() if res: inv_ids = [x[0] for x in res] - else: + else: select2 = " AND type = 'out_refund' AND free_comm ilike '%'||number||'%'" cr.execute(select + select2) - res=cr.fetchall() + res = cr.fetchall() if res: inv_ids = [x[0] for x in res] if inv_ids: @@ -578,7 +575,7 @@ class account_coda_import(osv.osv_memory): "\n There are multiple invoices matching the Invoice Amount and Reference." \ "\n A manual reconciliation is required.") \ % (st_line['ref']) - + if not payment_reference_match and match and inv_ids and len(inv_ids) == 1: invoice = inv_obj.browse(cr, uid, inv_ids[0]) partner = invoice.partner_id @@ -594,27 +591,27 @@ class account_coda_import(osv.osv_memory): st_line['reconcile'] = iml_ids[0] else: err_string = _('\nThe CODA parsing detected a database inconsistency while processing movement data record 2.3, seq nr %s!' \ - '\nPlease report this issue via your OpenERP support channel.') % line[2:10] + '\nPlease report this issue via your OpenERP support channel.') % line[2:10] err_code = 'R2008' if batch: return (err_code, err_string) - raise osv.except_osv(_('Error!'), err_string) - - # lookup partner via counterparty_number when invoice lookup failed + raise osv.except_osv(_('Error!'), err_string) + + # lookup partner via counterparty_number when invoice lookup failed if not match and counterparty_number: - transfer_account = filter(lambda x: counterparty_number in x, company_bank_accounts) + transfer_account = filter(lambda x: counterparty_number in x, company_bank_accounts) if transfer_account: st_line['account_id'] = transfer_acc match = True elif find_partner: - partner_bank_ids = partner_bank_obj.search(cr,uid,[('acc_number','=', counterparty_number)]) + partner_bank_ids = partner_bank_obj.search(cr, uid, [('acc_number', '=', counterparty_number)]) if not match and find_partner and partner_bank_ids: if len(partner_bank_ids) > 1: coda_parsing_note += _("\n Bank Statement '%%(name)s' line '%s':" \ "\n No partner record assigned: There are multiple partners with the same Bank Account Number '%s'!" \ "\n Please correct the configuration and perform the import again or otherwise change the corresponding entry manually in the generated Bank Statement.") \ % (st_line['ref'], counterparty_number) - else: + else: partner_bank = partner_bank_obj.browse(cr, uid, partner_bank_ids[0], context) st_line['partner_id'] = partner_bank.partner_id.id match = True @@ -634,21 +631,21 @@ class account_coda_import(osv.osv_memory): coda_parsing_note += _("\n Bank Statement '%%(name)s' line '%s':" \ "\n No matching partner record found!" \ "\n Please adjust the corresponding entry manually in the generated Bank Statement.") \ - % (st_line['ref']) + % (st_line['ref']) st_line['account_id'] = awaiting_acc - + # add bank account to partner record if match and st_line['account_id'] != transfer_acc and counterparty_number and update_partner: - partner_bank_ids = partner_bank_obj.search(cr,uid,[('acc_number','=', counterparty_number), ('partner_id', '=', st_line['partner_id'])], order='id') + partner_bank_ids = partner_bank_obj.search(cr, uid, [('acc_number', '=', counterparty_number), ('partner_id', '=', st_line['partner_id'])], order='id') if len(partner_bank_ids) > 1: # clean up partner bank duplicates, keep most recently created - _logger.warn('Duplicate Bank Accounts for partner_id %s have been removed, ids = %s', + _logger.warn('Duplicate Bank Accounts for partner_id %s have been removed, ids = %s', st_line['partner_id'], partner_bank_ids[:-1]) - partner_bank_obj.unlink(cr,uid, partner_bank_ids[:-1]) + partner_bank_obj.unlink(cr, uid, partner_bank_ids[:-1]) if not partner_bank_ids: feedback = update_partner_bank(self, cr, uid, st_line['counterparty_bic'], counterparty_number, st_line['partner_id'], counterparty_name) - if feedback: - coda_parsing_note += _("\n Bank Statement '%%(name)s' line '%s':") % st_line['ref'] + feedback + if feedback: + coda_parsing_note += _("\n Bank Statement '%%(name)s' line '%s':") % st_line['ref'] + feedback coda_statement_lines[st_line_seq] = st_line coda_statement['coda_statement_lines'] = coda_statement_lines @@ -660,18 +657,18 @@ class account_coda_import(osv.osv_memory): err_code = 'R2009' if batch: return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) + raise osv.except_osv(_('Data Error!'), err_string) elif line[0] == '3': # information data record 3 - + if line[1] == '1': # information data record 3.1 info_line = {} info_line['entry_date'] = st_line['entry_date'] info_line['type'] = 'information' st_line_seq = st_line_seq + 1 - info_line['sequence'] = st_line_seq + info_line['sequence'] = st_line_seq info_line['struct_comm_type'] = '' info_line['struct_comm_type_desc'] = '' info_line['communication'] = '' @@ -679,37 +676,37 @@ class account_coda_import(osv.osv_memory): info_line['trans_ref'] = line[10:31] # positions 32-38 : transaction code info_line['trans_type'] = line[31] - trans_type = filter(lambda x: info_line['trans_type'] == x['type'], trans_type_table) + trans_type = filter(lambda x: info_line['trans_type'] == x['type'], trans_type_table) if not trans_type: err_string = _('\nThe File contains an invalid CODA Transaction Type : %s!') % st_line['trans_type'] err_code = 'R3001' if batch: return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - info_line['trans_type_desc'] = trans_type[0]['description'] + raise osv.except_osv(_('Data Error!'), err_string) + info_line['trans_type_desc'] = trans_type[0]['description'] info_line['trans_family'] = line[32:34] - trans_family = filter(lambda x: (x['type'] == 'family') and (info_line['trans_family'] == x['code']), trans_code_table) + trans_family = filter(lambda x: (x['type'] == 'family') and (info_line['trans_family'] == x['code']), trans_code_table) if not trans_family: - err_string = _('\nThe File contains an invalid CODA Transaction Family : %s!') % st_line['trans_family'] + err_string = _('\nThe File contains an invalid CODA Transaction Family : %s!') % st_line['trans_family'] err_code = 'R3002' if batch: return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) + raise osv.except_osv(_('Data Error!'), err_string) info_line['trans_family_desc'] = trans_family[0]['description'] info_line['trans_code'] = line[34:36] - trans_code = filter(lambda x: (x['type'] == 'code') and (info_line['trans_code'] == x['code']) and (trans_family[0]['id'] == x['parent_id'][0]), + trans_code = filter(lambda x: (x['type'] == 'code') and (info_line['trans_code'] == x['code']) and (trans_family[0]['id'] == x['parent_id'][0]), trans_code_table) if trans_code: info_line['trans_code_desc'] = trans_code[0]['description'] else: info_line['trans_code_desc'] = _('Transaction Code unknown, please consult your bank.') info_line['trans_category'] = line[36:39] - trans_category = filter(lambda x: info_line['trans_category'] == x['category'], trans_category_table) + trans_category = filter(lambda x: info_line['trans_category'] == x['category'], trans_category_table) if trans_category: info_line['trans_category_desc'] = trans_category[0]['description'] else: - info_line['trans_category_desc'] = _('Transaction Category unknown, please consult your bank.') - # positions 40-113 : communication + info_line['trans_category_desc'] = _('Transaction Category unknown, please consult your bank.') + # positions 40-113 : communication if line[39] == '1': info_line['struct_comm_type'] = line[40:43] comm_type = filter(lambda x: info_line['struct_comm_type'] == x['code'], comm_type_table) @@ -726,7 +723,7 @@ class account_coda_import(osv.osv_memory): # positions 114-128 not processed coda_statement_lines[st_line_seq] = info_line coda_statement['coda_statement_lines'] = coda_statement_lines - + elif line[1] == '2': # information data record 3.2 if coda_statement['coda_statement_lines'][st_line_seq]['ref'] != line[2:10]: @@ -736,9 +733,9 @@ class account_coda_import(osv.osv_memory): if batch: return (err_code, err_string) raise osv.except_osv(_('Error!'), err_string) - coda_statement['coda_statement_lines'][st_line_seq]['name'] += line[10:115] + coda_statement['coda_statement_lines'][st_line_seq]['name'] += line[10:115] coda_statement['coda_statement_lines'][st_line_seq]['communication'] += line[10:115] - + elif line[1] == '3': # information data record 3.3 if coda_statement['coda_statement_lines'][st_line_seq]['ref'] != line[2:10]: @@ -750,7 +747,7 @@ class account_coda_import(osv.osv_memory): raise osv.except_osv(_('Error!'), err_string) coda_statement['coda_statement_lines'][st_line_seq]['name'] += line[10:100] coda_statement['coda_statement_lines'][st_line_seq]['communication'] += line[10:100] - + elif line[0] == '4': # free communication data record 4 comm_line = {} @@ -761,11 +758,11 @@ class account_coda_import(osv.osv_memory): comm_line['communication'] = comm_line['name'] = line[32:112] coda_statement_lines[st_line_seq] = comm_line coda_statement['coda_statement_lines'] = coda_statement_lines - + elif line[0] == '8': # new balance record last_transaction = main_move_stack[-1] - if last_transaction['type'] == 'globalisation' and not last_transaction.get('detail_cnt'): + if last_transaction['type'] == 'globalisation' and not last_transaction.get('detail_cnt'): # demote record with globalisation code from 'globalisation' to 'general' when no detail records main_st_line_seq = main_move_stack[-1]['sequence'] to_demote = coda_statement['coda_statement_lines'][main_st_line_seq] @@ -778,7 +775,7 @@ class account_coda_import(osv.osv_memory): # add closing globalisation level on previous detail record in order to correctly close # moves that have been 'promoted' to globalisation if main_move_stack[-1].get('detail_cnt') and main_move_stack[-1].get('promoted'): - closeglobalise = coda_statement['coda_statement_lines'][st_line_seq-1] + closeglobalise = coda_statement['coda_statement_lines'][st_line_seq - 1] closeglobalise.update({ 'glob_lvl_flag': main_move_stack[-1]['glob_lvl_flag'], }) @@ -788,10 +785,10 @@ class account_coda_import(osv.osv_memory): if line[41] == '1': # 1=Debit bal_end = - bal_end coda_statement['balance_end_real'] = bal_end - if coda_statement['new_balance_date']: - period_id = period_obj.search(cr , uid, [('date_start' ,'<=', coda_statement['new_balance_date']), ('date_stop','>=',coda_statement['new_balance_date'])]) + if coda_statement['new_balance_date']: + period_id = period_obj.search(cr, uid, [('date_start', '<=', coda_statement['new_balance_date']), ('date_stop', '>=', coda_statement['new_balance_date'])]) else: - period_id = period_obj.search(cr , uid, [('date_start' ,'<=', coda_statement['date']), ('date_stop','>=',coda_statement['date'])]) + period_id = period_obj.search(cr, uid, [('date_start', '<=', coda_statement['date']), ('date_stop', '>=', coda_statement['date'])]) if not period_id: err_string = _("\nThe CODA Statement New Balance date doesn't fall within a defined Accounting Period!" \ "\nPlease create the Accounting Period for date %s.") % coda_statement['new_balance_date'] @@ -802,7 +799,7 @@ class account_coda_import(osv.osv_memory): coda_statement['period_id'] = period_id[0] if coda_bank['coda_st_naming']: coda_statement['name'] = coda_bank['coda_st_naming'] % { - 'code': coda_bank['journal_code'] or '', + 'code': coda_bank['journal_code'] or '', 'year': coda_statement['new_balance_date'] and coda_statement['new_balance_date'][:4] or coda_statement['date'][:4], 'y': coda_statement['new_balance_date'] and coda_statement['new_balance_date'][2:4] or coda_statement['date'][2:4], 'coda': coda_statement['coda_seq_number'], @@ -811,14 +808,14 @@ class account_coda_import(osv.osv_memory): } else: coda_statement['name'] = '/' - + elif line[0] == '9': # footer record - coda_statement['balance_min'] = list2float(line[22:37]) + coda_statement['balance_min'] = list2float(line[22:37]) coda_statement['balance_plus'] = list2float(line[37:52]) if not bal_end: coda_statement['balance_end_real'] = coda_statement['balance_start'] + coda_statement['balance_plus'] - coda_statement['balance_min'] - if coda_parsing_note: + if coda_parsing_note: coda_statement['coda_parsing_note'] = '\nStatement Line matching results:' + coda_parsing_note else: coda_statement['coda_parsing_note'] = '' @@ -826,28 +823,28 @@ class account_coda_import(osv.osv_memory): #end for err_string = '' - err_code = '' + err_code = '' coda_id = 0 coda_note = '' line_note = '' - + try: - coda_id = coda_obj.create(cr, uid,{ - 'name' : codafilename, + coda_id = coda_obj.create(cr, uid, { + 'name': codafilename, 'coda_data': codafile, - 'coda_creation_date' : coda_statement['date'], + 'coda_creation_date': coda_statement['date'], 'date': fields.date.context_today(self, cr, uid, context=context), 'user_id': uid, }) context.update({'coda_id': coda_id}) - + except osv.except_osv, e: cr.rollback() err_string = _('\nApplication Error : ') + str(e) except Exception, e: cr.rollback() err_string = _('\nSystem Error : ') + str(e) - except : + except: cr.rollback() err_string = _('\nUnknown Error : ') + str(e) if err_string: @@ -859,40 +856,40 @@ class account_coda_import(osv.osv_memory): nb_err = 0 err_string = '' coda_st_ids = [] - bk_st_ids = [] - + bk_st_ids = [] + for statement in coda_statements: - + # The CODA Statement info is written to two objects: 'coda.bank.statement' and 'account.bank.statement' try: normal2info = False lines = statement['coda_statement_lines'] - if not statement['first_transaction_date']: - normal2info = True # don't create a bank statement for CODA's without transactions + if not statement['first_transaction_date']: + normal2info = True # don't create a bank statement for CODA's without transactions else: line_vals = [x for x in lines.itervalues()] transactions = filter(lambda x: (x['type'] in ['globalisation', 'general', 'supplier', 'customer']) and x['amount'], line_vals) if not transactions: - normal2info = True # don't create a bank statement for CODA's without transactions + normal2info = True # don't create a bank statement for CODA's without transactions if normal2info: - statement['type'] = 'info' # don't create a bank statement for CODA's without transactions + statement['type'] = 'info' # don't create a bank statement for CODA's without transactions statement['coda_parsing_note'] += _("\n\nThe CODA Statement %s does not contain transactions, hence no Bank Statement has been created." \ "\nSelect the 'CODA Bank Statement' to check the contents of %s.") \ - %(statement['name'], statement['name']) - + % (statement['name'], statement['name']) + coda_st_id = coda_st_obj.create(cr, uid, { 'name': statement['name'], 'type': statement['type'], 'coda_bank_account_id': statement['coda_bank_account_id'], - 'currency': statement['currency_id'], + 'currency': statement['currency_id'], 'journal_id': statement['journal_id'], 'coda_id': coda_id, 'date': statement['date'], 'coda_creation_date': statement['coda_creation_date'], 'period_id': statement['period_id'], 'old_balance_date': statement['old_balance_date'], - 'new_balance_date': statement['new_balance_date'], + 'new_balance_date': statement['new_balance_date'], 'balance_start': statement['balance_start'], 'balance_end_real': statement['balance_end_real'], }) @@ -904,10 +901,10 @@ class account_coda_import(osv.osv_memory): dup_ids = bank_st_obj.search(cr, uid, [('name', '=', statement['name']), ('company_id', '=', company_id)]) if dup_ids: discard = True - statement['type'] = 'info' # don't create a bank statement for duplicates + statement['type'] = 'info' # don't create a bank statement for duplicates statement['coda_parsing_note'] += _("\n\nThe Bank Statement %s already exists, hence no duplicate Bank Statement has been created." \ "\nSelect the 'CODA Bank Statement' to check the contents of %s.") \ - %(statement['name'], statement['name']) + % (statement['name'], statement['name']) # create only bank statement for CODA's of type 'normal' if statement['type'] == 'normal' and not discard: @@ -924,16 +921,16 @@ class account_coda_import(osv.osv_memory): if journal.default_debit_account_id and (journal.default_credit_account_id == journal.default_debit_account_id): balance_start_check = journal.default_debit_account_id.balance else: - nb_err += 1 + nb_err += 1 err_string += _('\nConfiguration Error in journal %s!' \ '\nPlease verify the Default Debit and Credit Account settings.') % journal.name break - if balance_start_check <> statement['balance_start']: + if balance_start_check != statement['balance_start']: balance_start_err_string = _('\nThe CODA Statement %s Starting Balance (%.2f) does not correspond with the previous Closing Balance (%.2f) in journal %s!') \ - % (statement['name'], statement['balance_start'], balance_start_check, journal.name) + % (statement['name'], statement['balance_start'], balance_start_check, journal.name) if statement['balance_start_enforce']: - nb_err += 1 - err_string += balance_start_err_string + nb_err += 1 + err_string += balance_start_err_string break else: statement['coda_parsing_note'] += '\n' + balance_start_err_string @@ -950,89 +947,90 @@ class account_coda_import(osv.osv_memory): } st_hook_error, st_vals = self._statement_hook(cr, uid, statement['coda_bank_params'], st_vals, context=context) if st_hook_error: - nb_err += 1 - err_string += st_hook_error + nb_err += 1 + err_string += st_hook_error break bk_st_id = bank_st_obj.create(cr, uid, st_vals, context=context) bk_st_ids.append(bk_st_id) coda_st_obj.write(cr, uid, [coda_st_id], {'statement_id': bk_st_id}, context=context) - + st_line_seq = 0 for x in lines: line = lines[x] - + if not line['type'] == 'communication': if line['trans_family'] in st_line_name_families: - line['name'] = get_st_line_name(line, context) + line['name'] = get_st_line_name(line, context) if line['type'] == 'information': if line['struct_comm_type'] in parse_comms_info: line['name'], line['communication'] = parse_comm_info(self, cr, uid, line, comm_type_table, context) elif line['struct_comm_type'] in parse_comms_move: - line['name'], line['communication'] = parse_comm_move(self, cr, uid, line, comm_type_table, context) + line['name'], line['communication'] = parse_comm_move(self, cr, uid, line, comm_type_table, context) elif line['struct_comm_type'] in parse_comms_move: line['name'], line['communication'] = parse_comm_move(self, cr, uid, line, comm_type_table, context) # handling non-transactional records : line['type'] in ['information', 'communication'] - + if line['type'] == 'information': - line['globalisation_id'] = glob_id_stack[-1][2] + #Check if this line can be deleted. glob_id_stack marked as undefined here + #line['globalisation_id'] = glob_id_stack[-1][2] line_note = _('Transaction Type' ': %s - %s' \ '\nTransaction Family: %s - %s' \ '\nTransaction Code: %s - %s' \ '\nTransaction Category: %s - %s' \ '\nStructured Communication Type: %s - %s' \ '\nCommunication: %s') \ - %(line['trans_type'], line['trans_type_desc'], + % (line['trans_type'], line['trans_type_desc'], line['trans_family'], line['trans_family_desc'], line['trans_code'], line['trans_code_desc'], line['trans_category'], line['trans_category_desc'], line['struct_comm_type'], line['struct_comm_type_desc'], line['communication']) - - coda_st_line_id = coda_st_line_obj.create(cr, uid, { + + coda_st_line_obj.create(cr, uid, { 'sequence': line['sequence'], - 'ref': line['ref'], + 'ref': line['ref'], 'name': line['name'].strip() or '/', - 'type' : 'information', - 'date': line['entry_date'], + 'type': 'information', + 'date': line['entry_date'], 'statement_id': coda_st_id, 'note': line_note, }) - + elif line['type'] == 'communication': line_note = _('Free Communication:\n %s') \ - %(line['communication']) - - coda_st_line_id = coda_st_line_obj.create(cr, uid, { + % (line['communication']) + + coda_st_line_obj.create(cr, uid, { 'sequence': line['sequence'], - 'ref': line['ref'], + 'ref': line['ref'], 'name': line['name'].strip() or '/', - 'type' : 'communication', + 'type': 'communication', 'date': statement['date'], 'statement_id': coda_st_id, 'note': line_note, }) - # handling transactional records, # line['type'] in ['globalisation', 'general', 'supplier', 'customer'] + # handling transactional records, # line['type'] in ['globalisation', 'general', 'supplier', 'customer'] else: - + if line['ref_move_detail'] == '0000': glob_id_stack = [(0, '', 0, '')] # initialise stack with tuples (glob_lvl_flag, glob_code, glob_id, glob_name) - + glob_lvl_flag = line['glob_lvl_flag'] - if glob_lvl_flag: - if glob_id_stack[-1][0] == glob_lvl_flag: + if glob_lvl_flag: + if glob_id_stack[-1][0] == glob_lvl_flag: line['globalisation_id'] = glob_id_stack[-1][2] glob_id_stack.pop() else: glob_name = line['name'].strip() or '/' glob_code = seq_obj.get(cr, uid, 'statement.line.global') glob_id = glob_obj.create(cr, uid, { - 'code': glob_code, + 'code': glob_code, 'name': glob_name, 'type': 'coda', 'parent_id': glob_id_stack[-1][2], @@ -1041,7 +1039,7 @@ class account_coda_import(osv.osv_memory): }) line['globalisation_id'] = glob_id glob_id_stack.append((glob_lvl_flag, glob_code, glob_id, glob_name)) - + line_note = _('Partner Name: %s \nPartner Account Number: %s' \ '\nTransaction Type: %s - %s' \ '\nTransaction Family: %s - %s' \ @@ -1050,64 +1048,64 @@ class account_coda_import(osv.osv_memory): '\nStructured Communication Type: %s - %s' \ '\nPayment Reference: %s' \ '\nCommunication: %s') \ - %(line['counterparty_name'], line['counterparty_number'], + % (line['counterparty_name'], line['counterparty_number'], line['trans_type'], line['trans_type_desc'], line['trans_family'], line['trans_family_desc'], line['trans_code'], line['trans_code_desc'], line['trans_category'], line['trans_category_desc'], line['struct_comm_type'], line['struct_comm_type_desc'], - line['payment_reference'], + line['payment_reference'], line['communication']) - + if line['type'] == 'globalisation': - - coda_st_line_id = coda_st_line_obj.create(cr, uid, { + + coda_st_line_obj.create(cr, uid, { 'sequence': line['sequence'], - 'ref': line['ref'], + 'ref': line['ref'], 'name': line['name'].strip() or '/', - 'type' : 'globalisation', - 'val_date' : line['val_date'], + 'type': 'globalisation', + 'val_date': line['val_date'], 'date': line['entry_date'], - 'globalisation_level': line['glob_lvl_flag'], - 'globalisation_amount': line['globalisation_amount'], - 'globalisation_id': line['globalisation_id'], + 'globalisation_level': line['glob_lvl_flag'], + 'globalisation_amount': line['globalisation_amount'], + 'globalisation_id': line['globalisation_id'], 'partner_id': line['partner_id'] or 0, 'account_id': line['account_id'], - 'payment_reference': line['payment_reference'], + 'payment_reference': line['payment_reference'], 'statement_id': coda_st_id, 'note': line_note, }) - else: # line['type'] in ['general', 'supplier', 'customer'] + else: # line['type'] in ['general', 'supplier', 'customer'] - if glob_lvl_flag == 0: + if glob_lvl_flag == 0: line['globalisation_id'] = glob_id_stack[-1][2] - if not line['account_id']: + if not line['account_id']: line['account_id'] = awaiting_acc - - coda_st_line_id = coda_st_line_obj.create(cr, uid, { + + coda_st_line_obj.create(cr, uid, { 'sequence': line['sequence'], - 'ref': line['ref'], - 'name': line['name'].strip() or '/', - 'type' : line['type'], - 'val_date' : line['val_date'], + 'ref': line['ref'], + 'name': line['name'].strip() or '/', + 'type': line['type'], + 'val_date': line['val_date'], 'date': line['entry_date'], 'amount': line['amount'], 'partner_id': line['partner_id'] or 0, 'counterparty_name': line['counterparty_name'], - 'counterparty_bic': line['counterparty_bic'], - 'counterparty_number': line['counterparty_number'], - 'counterparty_currency': line['counterparty_currency'], + 'counterparty_bic': line['counterparty_bic'], + 'counterparty_number': line['counterparty_number'], + 'counterparty_currency': line['counterparty_currency'], 'account_id': line['account_id'], - 'globalisation_level': line['glob_lvl_flag'], - 'globalisation_id': line['globalisation_id'], - 'payment_reference': line['payment_reference'], + 'globalisation_level': line['glob_lvl_flag'], + 'globalisation_id': line['globalisation_id'], + 'payment_reference': line['payment_reference'], 'statement_id': coda_st_id, 'note': line_note, }) if statement['type'] == 'normal': - if line['amount'] != 0.0: + if line['amount'] != 0.0: st_line_seq += 1 voucher_id = False line_name = line['name'].strip() @@ -1116,9 +1114,9 @@ class account_coda_import(osv.osv_memory): line_name = glob_id_stack[-1][3] or '/' else: line_name = '/' - + if line['reconcile']: - + move_line = move_line_obj.browse(cr, uid, line['reconcile'], context=context) company_currency_id = journal.company_id.currency_id.id currency_id = journal.currency.id @@ -1128,11 +1126,11 @@ class account_coda_import(osv.osv_memory): multi_currency = False context_multi_currency = context.copy() context_multi_currency.update({'date': line['entry_date']}) - + line_cr_ids = [] line_dr_ids = [] - amount_remaining = abs(line['amount']) - + amount_remaining = abs(line['amount']) + #for entry in entries: if move_line.reconcile_partial_id: amount_original = abs(move_line.amount_residual_currency) @@ -1142,7 +1140,7 @@ class account_coda_import(osv.osv_memory): if move_line.currency_id and move_line.amount_currency: amount_original = abs(move_line.amount_currency) else: - amount_original = currency_obj.compute(cr, uid, company_currency_id, currency_id, original_amount, context=context_multi_currency) + amount_original = currency_obj.compute(cr, uid, company_currency_id, currency_id, amount_original, context=context_multi_currency) if amount_remaining > 0: amount_voucher_line = min(amount_original, abs(amount_remaining)) amount_remaining -= amount_voucher_line @@ -1160,8 +1158,8 @@ class account_coda_import(osv.osv_memory): line_cr_ids += [(0, 0, voucher_line_vals)] else: line_dr_ids += [(0, 0, voucher_line_vals)] - - voucher_vals = { + + voucher_vals = { 'type': line['type'] == 'supplier' and 'payment' or 'receipt', 'name': line_name, 'date': line['val_date'], @@ -1179,9 +1177,9 @@ class account_coda_import(osv.osv_memory): 'number': statement['name'] + '/' + str(st_line_seq), 'partner_id': line['partner_id'], } - + #_logger.warn('voucher_vals=%s, context=%s', voucher_vals, context) - context['journal_id'] = journal.id # add journal to context for __get_payment_rate_currency method + context['journal_id'] = journal.id # add journal to context for __get_payment_rate_currency method if line_cr_ids or line_dr_ids: voucher_id = voucher_obj.create(cr, uid, voucher_vals, context=context) else: @@ -1205,25 +1203,25 @@ class account_coda_import(osv.osv_memory): line['account_id'] = account_id st_line_vals = { - 'ref': line['ref'], + 'ref': line['ref'], 'name': line_name, - 'type' : line['type'], - 'val_date' : line['val_date'], + 'type': line['type'], + 'val_date': line['val_date'], 'date': line['entry_date'], 'amount': line['amount'], 'partner_id': line['partner_id'] or 0, 'counterparty_name': line['counterparty_name'], - 'counterparty_bic': line['counterparty_bic'], - 'counterparty_number': line['counterparty_number'], - 'counterparty_currency': line['counterparty_currency'], + 'counterparty_bic': line['counterparty_bic'], + 'counterparty_number': line['counterparty_number'], + 'counterparty_currency': line['counterparty_currency'], 'account_id': line['account_id'], - 'globalisation_id': line['globalisation_id'], - 'payment_reference': line['payment_reference'], + 'globalisation_id': line['globalisation_id'], + 'payment_reference': line['payment_reference'], 'statement_id': bk_st_id, 'voucher_id': voucher_id, 'note': line_note, } - + st_lines_vals = self._st_line_hook(cr, uid, statement['coda_bank_params'], st_line_vals, context=context) if not st_lines_vals: # removal of lines by the _coda_parsing_hook currently not supported : @@ -1234,7 +1232,7 @@ class account_coda_import(osv.osv_memory): for st_line_vals in st_lines_vals: # To DO : update sequence of statement lines and naming of associated vouchers/moves when the hook returns multiple lines st_line_vals.update({'sequence': st_line_seq}) - bank_st_line_id = bank_st_line_obj.create(cr, uid, st_line_vals, context=context) + bank_st_line_obj.create(cr, uid, st_line_vals, context=context) if st_line_vals['voucher_id']: voucher = voucher_obj.browse(cr, uid, st_line_vals['voucher_id'], context=context) move_line = move_line_obj.browse(cr, uid, line['reconcile'], context=context) @@ -1247,7 +1245,7 @@ class account_coda_import(osv.osv_memory): coda_st_obj.write(cr, uid, [coda_st_id], {}, context=context) # calculate balance st_balance = coda_st_obj.read(cr, uid, coda_st_id, ['balance_end', 'balance_end_real'], context=context) - if st_balance['balance_end'] <> st_balance['balance_end_real']: + if st_balance['balance_end'] != st_balance['balance_end_real']: err_string += _('\nIncorrect ending Balance in CODA Statement %s for Bank Account %s!') \ % (statement['coda_seq_number'], (statement['acc_number'] + ' (' + statement['currency'] + ') - ' + statement['description'])) if statement['type'] == 'normal': @@ -1255,9 +1253,9 @@ class account_coda_import(osv.osv_memory): break else: statement['coda_parsing_note'] += '\n' + err_string - - if statement['type'] == 'normal': - bank_st_obj.button_dummy(cr, uid, [bk_st_id], context=context) # calculate balance + + if statement['type'] == 'normal': + bank_st_obj.button_dummy(cr, uid, [bk_st_id], context=context) # calculate balance journal_name = journal.name else: journal_name = _('None') @@ -1270,16 +1268,16 @@ class account_coda_import(osv.osv_memory): '\nAccount Holder Name: %s' \ '\nDate: %s, Starting Balance: %.2f, Ending Balance: %.2f' \ '%s') \ - %(journal_name, + % (journal_name, coda_version, statement['coda_seq_number'], statement['paper_nb_seq_number'], (statement['acc_number'] + ' (' + statement['currency'] + ') - ' + statement['description']), statement['acc_holder'], statement['date'], float(statement['balance_start']), float(statement['balance_end_real']), - statement['coda_parsing_note'] % {'name':coda_statement['name']}) + statement['coda_parsing_note'] % {'name': coda_statement['name']}) if statement.get('separate_application') != '00000': - coda_note += _('\nCode Separate Application: %s') %statement['separate_application'] \ + coda_note += _('\nCode Separate Application: %s') % statement['separate_application'] \ except osv.except_osv, e: cr.rollback() @@ -1293,25 +1291,25 @@ class account_coda_import(osv.osv_memory): nb_err += 1 err_string += _('\nSystem Error : ') + str(e) tb = ''.join(format_exception(*exc_info())) - _logger.error('System Error while processing Statement %s\n%s', - statement.get('name', '/'),tb) - except : + _logger.error('System Error while processing Statement %s\n%s', + statement.get('name', '/'), tb) + except: cr.rollback() nb_err += 1 err_string = _('\nUnknown Error : ') + str(e) tb = ''.join(format_exception(*exc_info())) _logger.error('Unknown Error while processing Statement %s\n%s', - statement.get('name', '/'),tb) + statement.get('name', '/'), tb) # end 'for statement in coda_statements' - + coda_note_header = _('CODA File is Imported :') coda_note_footer = _('\n\nNumber of statements : ') + str(len(coda_st_ids)) err_log = err_log + _('\nNumber of errors : ') + str(nb_err) + '\n' if not nb_err: note = coda_note_header + coda_note + coda_note_footer - coda_obj.write(cr, uid,[coda_id],{'note': note }) + coda_obj.write(cr, uid, [coda_id], {'note': note}) cr.commit() if batch: return None @@ -1321,12 +1319,12 @@ class account_coda_import(osv.osv_memory): err_code = 'G0002' return (err_code, err_string) raise osv.except_osv(_('CODA Import failed !'), err_string) - - context.update({ 'bk_st_ids': bk_st_ids}) + + context.update({'bk_st_ids': bk_st_ids}) model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'account_coda_import_result_view')], context=context) resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] self.write(cr, uid, ids, {'note': note}, context=context) - + return { 'name': _('Import CODA File result'), 'res_id': ids[0], @@ -1341,16 +1339,16 @@ class account_coda_import(osv.osv_memory): } def _statement_hook(self, cr, uid, coda_bank_params, st_vals, context=None): - """ + """ Use this method to take customer specific actions based upon the bank statement data. Returns: st_hook_error : False or string with error message - st_vals + st_vals """ return False, st_vals def _st_line_hook(self, cr, uid, coda_bank_params, st_line_vals, context=None): - """ + """ Use this method to adapt the statement line created by the CODA parsing to customer specific needs. """ @@ -1374,43 +1372,50 @@ class account_coda_import(osv.osv_memory): res_model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, module, xml_id) action = self.pool.get('ir.actions.act_window').read(cr, uid, res_id, context=context) domain = eval(action.get('domain') or '[]') - domain += [('id','in', context.get('bk_st_ids', False))] + domain += [('id', 'in', context.get('bk_st_ids', False))] action.update({'domain': domain}) return action - + account_coda_import() + def repl_special(s): s = s.replace("\'", "\'" + "'") return s + def str2date(date_str): try: - return time.strftime('%Y-%m-%d', time.strptime(date_str,'%d%m%y')) + return time.strftime('%Y-%m-%d', time.strptime(date_str, '%d%m%y')) except: return False + def str2time(time_str): return time_str[:2] + ':' + time_str[2:] + def str2float(str): try: return float(str) except: return 0.0 + def list2float(lst): try: - return str2float((lambda s : s[:-3] + '.' + s[-3:])(lst)) + return str2float((lambda s: s[:-3] + '.' + s[-3:])(lst)) except: return 0.0 + def number2float(s, d): try: - return float(s[:len(s)-d] + '.' + s[len(s)-d:]) + return float(s[:len(s) - d] + '.' + s[len(s) - d:]) except: return False + def _get_acc_numbers(acc_number): #TODO this method is needed because the iban and bank account fields have been merged together. But sometimes we # need to retrieve the normal bank account from the IBAN. This should be globalized and defined as a method on the @@ -1422,6 +1427,7 @@ def _get_acc_numbers(acc_number): from base_iban.base_iban import _ref_iban, _format_iban + def calc_iban_checksum(country, bban): bban = bban.replace(' ', '').upper() + country.upper() + '00' base = '' @@ -1433,16 +1439,18 @@ def calc_iban_checksum(country, bban): kk = 98 - int(base) % 97 return str(kk).rjust(2, '0') + def check_bban(country, bban): if country == 'BE': try: int(bban) except: - return False + return False if len(bban) != 12: return False return True + def check_iban(iban): """ Check the IBAN number (logic partially based upon base_iban module, cf. is_iban_valid method) @@ -1458,20 +1466,21 @@ def check_iban(iban): iban2 = "" for char in iban: if char.isalpha(): - iban2 += str(ord(char)-87) + iban2 += str(ord(char) - 87) else: iban2 += char #iban is correct if modulo 97 == 1 return int(iban2) % 97 == 1 + def get_bank(self, cr, uid, bic, iban): - country_obj = self.pool.get('res.country') + country_obj = self.pool.get('res.country') bank_obj = self.pool.get('res.bank') bank_id = False bank_name = False - feedback = False + feedback = False bank_country = iban[:2] try: bank_country_id = country_obj.search(cr, uid, [('code', '=', bank_country)])[0] @@ -1505,7 +1514,7 @@ def get_bank(self, cr, uid, bic, iban): feedback = _("\n Bank lookup failed. Please define a Bank with Code '%s' and Country '%s' !") \ % (bank_code, country.name) else: - if not bic: + if not bic: feedback = _("\n Bank lookup failed due to missing BIC in Bank Statement for IBAN '%s' !") \ % (iban) else: @@ -1518,10 +1527,11 @@ def get_bank(self, cr, uid, bic, iban): 'country': bank_country_id, }) else: - bank_id = bank_ids[0] - + bank_id = bank_ids[0] + return bank_id, bic, bank_name, feedback - + + def update_partner_bank(self, cr, uid, bic, iban, partner_id, counterparty_name): partner_bank_obj = self.pool.get('res.partner.bank') bank_id = False @@ -1531,7 +1541,6 @@ def update_partner_bank(self, cr, uid, bic, iban, partner_id, counterparty_name) if not bank_id: return feedback else: - bban = iban #convert belgian BBAN numbers to IBAN if check_bban('BE', iban): kk = calc_iban_checksum('BE', iban) @@ -1541,22 +1550,23 @@ def update_partner_bank(self, cr, uid, bic, iban, partner_id, counterparty_name) return feedback if bank_id: - partner_bank_id = partner_bank_obj.create(cr, uid, { + partner_bank_obj.create(cr, uid, { 'partner_id': partner_id, 'name': counterparty_name, 'bank': bank_id, 'state': 'iban', 'bank_bic': bic, - 'bank_name': bank_name, + 'bank_name': bank_name, 'acc_number': iban, }) return feedback -indent = '\n' + 8*' ' +indent = '\n' + 8 * ' ' st_line_name_families = ['13', '35', '41', '80'] parse_comms_move = ['100', '101', '102', '103', '105', '106', '107', '108', '111', '113', '114', '115', '121', '122', '123', '124', '125', '126', '127'] parse_comms_info = ['001', '002', '004', '005', '006', '007', '107', '008', '009', '010', '011'] + def get_st_line_name(line, context): #_logger.warn('get_st_line_name - entry').warn('ref = %s, family = %s, code = %s, categ = %s', line['ref'], line['trans_family'], line['trans_code'], line['trans_category']) st_line_name = line['name'] @@ -1572,6 +1582,7 @@ def get_st_line_name(line, context): return st_line_name + def parse_comm_move(self, cr, uid, line, comm_type_table, context): #_logger.warn('parse_comm_move - entry, ref = %s, family = %s, code = %s, categ = %s, comm_type = %s, name = %s', line['ref'], line['trans_family'], line['trans_code'], line['trans_category'], line['struct_comm_type'], line['name']) comm_type = line['struct_comm_type'] @@ -1628,7 +1639,7 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): '1': _('direct debit cancelled or nonexistent'), '2': _('refusal - other reason'), 'D': _('payer disagrees'), - 'E': _('direct debit number linked to another identification number of the creditor')} + 'E': _('direct debit number linked to another identification number of the creditor')} st_line_name = _('Direct debit - DOM\'80') direct_debit_number = comm[0:12].strip() pivot_date = str2date(comm[12:18]) @@ -1649,7 +1660,7 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): st_line_comm += indent + _('Interest rates, calculation basis') + ': %.2f' % list2float(comm[15:30]) + \ indent + _('Interest') + ': %.2f' % list2float(comm[30:42]) - if comm_type =='111': + if comm_type == '111': card_schemes = { '1': 'Bancontact/Mister Cash', '2': _('Private'), @@ -1781,10 +1792,10 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): if comm_type == '123': starting_date = str2date(comm[0:6]) maturity_date = comm[6:12] == '999999' and _('guarantee without fixed term') or str2date(comm[0:6]) - basic_amount = list2float(comm[12:27]) + basic_amount = list2float(comm[12:27]) percent = number2float(comm[27:39], 8) term = comm[39:43].lstrip('0') - minimum = comm[43] == '1' and True or False + minimum = comm[43] == '1' and True or False guarantee_number = comm[44:57].strip() st_line_comm = '\n' + indent + st_line_name + indent + _('Starting Date') + ': %s' % starting_date st_line_comm += indent + _('Maturity Date') + ': %s' % maturity_date @@ -1793,7 +1804,7 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): st_line_comm += indent + _('Term in days') + ': %s' % term st_line_comm += indent + (minimum and _('Minimum applicable') or _('Minimum not applicable')) st_line_comm += indent + _('Guarantee Number') + ': %s' % guarantee_number - + if comm_type == '124': card_issuers = { '1': 'Mastercard', @@ -1812,7 +1823,7 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): st_line_comm += indent + _('Invoice Number') + ': %s' % invoice_number st_line_comm += indent + _('Identification Number') + ': %s' % identification_number st_line_comm += indent + _('Date') + ': %s' % date - + if comm_type == '125': if line['trans_family'] not in st_line_name_families: st_line_name = _('Credit') @@ -1836,31 +1847,31 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): st_line_comm += indent + _('End Date') + ': %s' % end_date st_line_comm += indent + _('Nominal Interest Rate or Rate of Charge') + ': %.4f' % rate st_line_comm += indent + _('Transaction Reference') + ': %s' % trans_reference - + if comm_type == '127': direct_debit_types = { '0': _('unspecified'), '1': _('recurrent'), '2': _('one-off'), '3': _('1-st (recurrent)'), - '4': _('last (recurrent)')} + '4': _('last (recurrent)')} direct_debit_schemes = { '0': _('unspecified'), '1': _('SEPA core'), - '2': _('SEPA B2B')} + '2': _('SEPA B2B')} paid_refusals = { '0': _('paid'), '1': _('technical problem'), '2': _('refusal - reason not specified'), '3': _('debtor disagrees'), - '4': _('debtor\'s account problem')} + '4': _('debtor\'s account problem')} R_types = { '0': _('paid'), '1': _('reject'), '2': _('return'), '3': _('refund'), '4': _('reversal'), - '5': _('cancellation')} + '5': _('cancellation')} st_line_name = _('European direct debit (SEPA)') settlement_date = str2date(comm[0:6]) direct_debit_type = direct_debit_types.get(comm[6], '') @@ -1880,14 +1891,15 @@ def parse_comm_move(self, cr, uid, line, comm_type_table, context): st_line_comm += indent + _('Communication') + ': %s' % comm_zone st_line_comm += indent + _('R transaction Type') + ': %s' % R_type st_line_comm += indent + _('Reason') + ': %s' % reason - + return st_line_name, st_line_comm + def parse_comm_info(self, cr, uid, line, comm_type_table, context): comm_type = line['struct_comm_type'] comm = st_line_comm = line['communication'] st_line_name = line['name'] - + if comm_type == '001': st_line_name = filter(lambda x: comm_type == x['code'], comm_type_table)[0]['description'] st_line_comm = '\n' + indent + st_line_name + indent + _('Name') + ': %s' % comm[0:70].strip() @@ -1900,7 +1912,6 @@ def parse_comm_info(self, cr, uid, line, comm_type_table, context): st_line_comm = comm.strip() if comm_type == '006': - amount_sign = comm[48] amount = (comm[48] == '1' and '-' or '') + ('%.2f' % list2float(comm[33:48])) + ' ' + comm[30:33] st_line_name = filter(lambda x: comm_type == x['code'], comm_type_table)[0]['description'] st_line_comm = '\n' + indent + st_line_name + indent + _('Description of the detail') + ': %s' % comm[0:30].strip() @@ -1912,5 +1923,4 @@ def parse_comm_info(self, cr, uid, line, comm_type_table, context): 'Please contact Noviat (info@noviat.be) for more information about the development roadmap', comm_type) return st_line_name, st_line_comm - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: