diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index e7e3f740067..dc5dc504da4 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -546,7 +546,7 @@ class account_bank_statement_line(osv.osv): _name = "account.bank.statement.line" _description = "Bank Statement Line" _columns = { - 'name': fields.char('Communication', size=64, required=True), + 'name': fields.char('Communication', required=True), 'date': fields.date('Date', required=True), 'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')), 'type': fields.selection([ diff --git a/addons/l10n_be_coda/__openerp__.py b/addons/l10n_be_coda/__openerp__.py index 2c8931f484c..0cb29bcc002 100644 --- a/addons/l10n_be_coda/__openerp__.py +++ b/addons/l10n_be_coda/__openerp__.py @@ -90,15 +90,9 @@ V2.2 specifications. If required, you can manually adjust the descriptions via the CODA configuration menu. ''', 'images' : ['images/coda_logs.jpeg','images/import_coda_logs.jpeg'], - 'depends': ['account_voucher','base_iban', 'l10n_be_invoice_bba', 'account_bank_statement_extensions'], + 'depends': ['account_voucher','base_iban', 'l10n_be_invoice_bba',], 'demo': [], 'data': [ - 'l10n_be_coda_trans_type.xml', - 'l10n_be_coda_trans_code.xml', - 'l10n_be_coda_trans_category.xml', - 'l10n_be_coda_comm_type.xml', - 'security/ir.model.access.csv', - 'security/account_security.xml', 'l10n_be_coda_wizard.xml', 'l10n_be_coda_view.xml', ], diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py index 7f7572f5be9..2496cb20371 100644 --- a/addons/l10n_be_coda/l10n_be_coda.py +++ b/addons/l10n_be_coda/l10n_be_coda.py @@ -21,399 +21,57 @@ ############################################################################## from osv import osv, fields -import decimal_precision as dp -from tools.translate import _ -class coda_bank_account(osv.osv): - _name= 'coda.bank.account' - _description= 'CODA Bank Account Configuration' - - def _check_currency(self, cr, uid, ids, context=None): - obj_cba = self.browse(cr, uid, ids[0], context=context) - if (obj_cba.state == 'normal') and obj_cba.journal: - if obj_cba.journal.currency and (obj_cba.currency != obj_cba.journal.currency): - return False - if not obj_cba.journal.currency and (obj_cba.currency != obj_cba.company_id.currency_id): - return False - return True - - _columns = { - 'name': fields.char('Name', size=64, 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.'), - 'description2': fields.char('Secondary Account Description', size=35, - help='The Primary or Secondary Account Description should match the corresponding Account Description in the CODA file.'), - 'state': fields.selection([ - ('normal', 'Normal'), - ('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)]}, - help='Bank Journal for the Bank Statement'), - 'currency': fields.many2one('res.currency', 'Currency', required=True, - 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" - "\n\nVariables:" \ - "\nBank Journal Code: %(code)s" \ - "\nCurrent Year with Century: %(year)s" \ - "\nCurrent Year without Century: %(y)s" \ - "\nCODA sequence number: %(coda)s" \ - "\nPaper Statement sequence number: %(paper)s"), - 'def_payable': fields.many2one('account.account', 'Default Payable Account', domain=[('type', '=', 'payable')], required=True, - help= 'Set here the payable account that will be used, by default, if the partner is not found.'), - 'def_receivable': fields.many2one('account.account', 'Default Receivable Account', domain=[('type', '=', 'receivable')], required=True, - help= 'Set here the receivable account that will be used, by default, if the partner is not found.',), - '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.'), - '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).'), - 'find_bbacom': fields.boolean('Lookup Invoice', required=True, help='Partner lookup via the \'BBA\' Structured Communication field of the Invoice.'), - 'find_partner': fields.boolean('Lookup Partner', required=True, help='Partner lookup via Bank Account Number.'), - '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, - 'state': 'normal', - 'coda_st_naming': '%(code)s/%(y)s/%(coda)s', - 'active': True, - 'find_bbacom': True, - 'find_partner': True, - '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 !'), - ('account_uniq_2', 'unique (bank_id, description2, currency)', 'The combination of Bank Account, Account Description and Currency must be unique !'), - ] - _constraints = [ - (_check_currency, '\n\nConfiguration Error! \nThe Bank Account Currency should match the Journal Currency !', ['currency', 'journal']), - ] - _order = 'name' - - def name_get(self, cr, uid, ids, context=None): - res = [] - if not len(ids): - return res - for id in self.browse(cr, uid, ids, context=context): - res.append((id.id, (id.bank_id.iban or id.bank_id.acc_number) + ' (' + id.currency.name + ')' + \ - (id.description1 and (' - ' + id.description1) or ''))) - return res - - def copy(self, cr, uid, id, default=None, context=None): - cba = self.browse(cr, uid, id, context=context) - if not default: - default = {} - default = default.copy() - default.update( - journal_id=None, - description1=cba['description1'] or '', - description2=cba['description2'] or '', - name=_("%s (copy)") % (cba['name'] or ''), - 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 {} - -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), - 'coda_data': fields.binary('CODA File', 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), - '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), - } - _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: - context = {} - context.update({'coda_unlink': True}) - 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: - 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) - 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) - 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): - _name = 'account.coda.trans.type' - _description = 'CODA transaction type' - _rec_name = 'type' - _columns = { - 'type': fields.char('Transaction Type', size=1, required=True), - 'parent_id': fields.many2one('account.coda.trans.type', 'Parent'), - 'description': fields.text('Description', translate=True), - } - -account_coda_trans_type() - -class account_coda_trans_code(osv.osv): - _name = 'account.coda.trans.code' - _description = 'CODA transaction 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), - '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): - _name = 'account.coda.trans.category' - _description = 'CODA transaction 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): - _name = 'account.coda.comm.type' - _description = 'CODA structured communication type' - _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 !') - ] - -account_coda_comm_type() - -class coda_bank_statement(osv.osv): - _name = 'coda.bank.statement' - _description = 'CODA Bank Statement' - - def _default_journal_id(self, cr, uid, context=None): - if context is None: - context = {} - if context.get('journal_id', False): - return context['journal_id'] - return False - - def _end_balance(self, cursor, user, ids, name, attr, context=None): - res = {} - statements = self.browse(cursor, user, ids, context=context) - for statement in statements: - res[statement.id] = statement.balance_start - for line in statement.line_ids: - res[statement.id] += line.amount - for r in res: - res[r] = round(res[r], 2) - return res - - def _get_period(self, cr, uid, context=None): - periods = self.pool.get('account.period').find(cr, uid) - if periods: - return periods[0] - else: - return False - - _order = 'date desc' - _columns = { - 'name': fields.char('Name', size=64, required=True, readonly=True), - 'date': fields.date('Date', required=True, readonly=True), - 'coda_id': fields.many2one('account.coda', 'CODA Data File', ondelete='cascade'), - 'type': fields.selection([ - ('normal', 'Normal'), - ('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'), - '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), - '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'), - '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, - help='The currency of the CODA Bank Statement'), - '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, - '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: - context = {} - res = super(coda_bank_statement, self).search(cr, uid, args=args, offset=offset, limit=limit, order=order, - context=context, count=count) - if context.get('bank_statement', False) and not res: - raise osv.except_osv('Warning', _('No CODA Bank Statement found for this Bank Statement!')) - return res - - def unlink(self, cr, uid, ids, context=None): - if context is None: - context = {} - 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 = [] - 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 - for coda_statement in self.browse(cr, uid, new_ids, context=context): - 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." \ - "\nPlease undo this action first.") \ - % (coda_statement.name, coda_statement.journal_id.name)) - else: - if not context.get('coda_unlink', False): - if coda_statement.coda_id and coda_obj.exists(cr, uid, coda_statement.coda_id.id, context=context): - 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) - - 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 = { - 'coda_statement_id': fields.many2one('coda.bank.statement', 'Associated CODA Bank Statement'), + 'coda_note': fields.text('CODA Notes'), } - def unlink(self, cr, uid, ids, context=None): - if context is None: - context = {} - context.update({'bank_statement_unlink': True}) - coda_obj = self.pool.get('account.coda') - 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 = [] - 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): - 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) - if not context.get('coda_unlink', False): - if statement.coda_statement_id \ - and coda_st_obj.exists(cr, uid, statement.coda_statement_id.id, context=context) \ - and statement.coda_statement_id.coda_id \ - and coda_obj.exists(cr, uid, statement.coda_statement_id.coda_id.id, context=context): - coda_obj.unlink(cr, uid, [statement.coda_statement_id.coda_id.id], context=context) - - 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' - _description = 'CODA Bank Statement Line' +class account_bank_statement_line(osv.osv): + _inherit = 'account.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'), # remove required=True - 'type': fields.selection([ - ('supplier','Supplier'), - ('customer','Customer'), - ('general','General'), - ('globalisation','Globalisation'), - ('information','Information'), - ('communication','Free Communication'), - ], 'Type', required=True), - '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_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"), - '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), - '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), + 'coda_account_number': fields.char('Account Number', help="The Counter Party Account Number") } - def unlink(self, cr, uid, ids, context=None): - if context is None: - context = {} - if context.get('block_statement_line_delete', False): - raise osv.except_osv('Warning', _('Delete operation not allowed.')) - return super(account_bank_statement_line, self).unlink(cr, uid, ids, context=context) + def create(self, cr, uid, data, context=None): + """ + This function creates a Bank Account Number if, for a bank statement line, + the partner_id field and the coda_account_number field are set, + and the account number does not exist in the database + """ + if 'partner_id' in data and data['partner_id'] and 'coda_account_number' in data and data['coda_account_number']: + acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', data['coda_account_number'])]) + if len(acc_number_ids) == 0: + try: + type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') + type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) + self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': data['coda_account_number'], 'partner_id': data['partner_id'], 'state': type_id.code}, context=context) + except ValueError: + pass + return super(account_bank_statement_line, self).create(cr, uid, data, context=context) -coda_bank_statement_line() -class account_bank_statement_line_global(osv.osv): - _inherit = 'account.bank.statement.line.global' - _columns = { - 'coda_statement_line_ids': fields.one2many('coda.bank.statement.line', 'globalisation_id', 'CODA Bank Statement Lines', readonly=True), - } -account_bank_statement_line_global() + def write(self, cr, uid, ids, vals, context=None): + super(account_bank_statement_line, self).write(cr, uid, ids, vals, context) + """ + Same as create function above, but for write function + """ + if 'partner_id' in vals: + for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): + if line.coda_account_number: + acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', line.coda_account_number)]) + if len(acc_number_ids) == 0: + try: + type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') + type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) + self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': line.coda_account_number, 'partner_id': vals['partner_id'], 'state': type_id.code}, context=context) + except ValueError: + pass + return True + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_be_coda/l10n_be_coda_comm_type.xml b/addons/l10n_be_coda/l10n_be_coda_comm_type.xml deleted file mode 100644 index 9a042ec48d2..00000000000 --- a/addons/l10n_be_coda/l10n_be_coda_comm_type.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - 001 - Data concerning the counterparty - - - 002 - Communication of the bank - - - 003 - RBP data - - - 004 - Counterparty’s banker - - - 005 - Data concerning the correspondent - - - 006 - Information concerning the detail amount - - - 007 - Information concerning the detail cash - - - 008 - Identification of the de ultimate beneficiary/creditor (SEPA SCT/SDD) - - - 009 - Identification of the de ultimate ordering customer/debtor (SEPA SCT/SDD) - - - 010 - Information pertaining to sale or purchase of securities - - - 011 - Information pertaining to coupons - - - 100 - (SEPA) payment with a structured format communication applying the ISO standard 11649: Structured creditor reference to remittance information - - - 101 - Credit transfer or cash payment with structured format communication - - - 102 - Credit transfer or cash payment with reconstituted structured format communication - - - 103 - number (e.g. of the cheque, of the card, etc.) - - - 104 - Equivalent in EUR - - - 105 - original amount of the transaction - - - 106 - Method of calculation (VAT, withholding tax on income, commission, etc.) - - - 107 - Direct debit – DOM’80 - - - 108 - Closing - - - 111 - POS credit – Globalisation - - - 112 - ATM payment (usually Eurocheque card) - - - 113 - ATM/POS debit - - - 114 - POS credit - individual transaction - - - 115 - Terminal cash deposit - - - 120 - Correction of a transaction - - - 121 - Commercial bills - - - 122 - Bills - calculation of interest - - - 123 - Fees and commissions - - - 124 - Number of the credit card - - - 125 - Credit - - - 126 - Term investments - - - 127 - European direct debit (SEPA) - - - - diff --git a/addons/l10n_be_coda/l10n_be_coda_trans_category.xml b/addons/l10n_be_coda/l10n_be_coda_trans_category.xml deleted file mode 100644 index 192240cf8aa..00000000000 --- a/addons/l10n_be_coda/l10n_be_coda_trans_category.xml +++ /dev/null @@ -1,440 +0,0 @@ - - - - - - - 000 - Net amount - - - 001 - Interest received - - - 002 - Interest paid - - - 003 - Credit commission - - - 004 - Postage - - - 005 - Renting of letterbox - - - 006 - Various fees/commissions - - - 007 - Access right to database - - - 008 - Information charges - - - 009 - Travelling expenses - - - 010 - Writ service fee - - - 011 - VAT - - - 012 - Exchange commission - - - 013 - Payment commission - - - 014 - Collection commission - - - 015 - Correspondent charges - - - 016 - BLIW/IBLC dues - - - 017 - Research costs - - - 018 - Tental guarantee charges - - - 019 - Tax on physical delivery - - - 020 - Costs of physical delivery - - - 021 - Costs for drawing up a bank cheque - - - 022 - Priority costs - - - 023 - Exercising fee - - - 024 - Growth premium - - - 025 - Individual entry for exchange charges - - - 026 - Handling commission - - - 027 - Charges for unpaid bills - - - 028 - Fidelity premium - - - 029 - Protest charges - - - 030 - Account insurance - - - 031 - Charges foreign cheque - - - 032 - Drawing up a circular cheque - - - 033 - Charges for a foreign bill - - - 034 - Reinvestment fee - - - 035 - Charges foreign documentary bill - - - 036 - Costs relating to a refused cheque - - - 037 - Commission for handling charges - - - 039 - Telecommunications - - - 041 - Credit card costs - - - 042 - Payment card costs - - - 043 - Insurance costs - - - 045 - Handling costs - - - 047 - Charges extension bill - - - 049 - Fiscal stamps/stamp duty - - - 050 - Capital term investment - - - 051 - Withholding tax - - - 052 - Residence state tax - - - 053 - Printing of forms - - - 055 - Repayment loan or credit capital - - - 057 - Interest subsidy - - - 058 - Capital premium - - - 059 - Default interest - - - 061 - Charging fees for transactions - - - 063 - Rounding differences - - - 065 - Interest payment advice - - - 066 - Fixed loan advance - reimbursement - - - 067 - Fixed loan advance - extension - - - 068 - Countervalue of an entry - - - 069 - Forward arbitrage contracts : sum to be supplied by customer - - - 070 - Forward arbitrage contracts : sum to be supplied by bank - - - 071 - Fixed loan advance - availability - - - 072 - Countervalue of commission to third party - - - 073 - Costs of ATM abroad - - - 074 - Mailing costs - - - 100 - Gross amount - - - 200 - Overall documentary credit charges - - - 201 - Advice notice commission - - - 202 - Advising commission | Additional advising commission - - - 203 - Confirmation fee | Additional confirmation fee | Commitment fee | Flat fee | Confirmation reservation commission | Additional reservation commission - - - 204 - Amendment fee - - - 205 - Documentary payment commission | Document commission | Drawdown fee | Negotiation fee - - - 206 - Surety fee/payment under reserve - - - 207 - Non-conformity fee - - - 208 - Commitment fee deferred payment - - - 209 - Transfer commission - - - 210 - Commitment fee - - - 211 - Credit arrangement fee | Additional credit arrangement fee - - - 212 - Warehousing fee - - - 213 - Financing fee - - - 214 - Issue commission (delivery order) - - - 400 - Acceptance fee - - - 401 - Visa charges - - - 402 - Certification costs - - - 403 - Minimum discount rate - - - 404 - Discount commission - - - 405 - Bill guarantee commission - - - 406 - Collection charges - - - 407 - Costs Article 45 - - - 408 - Cover commission - - - 409 - Safe deposit charges - - - 410 - Reclamation charges - - - 411 - Fixed collection charge - - - 412 - Advice of expiry charges - - - 413 - Acceptance charges - - - 414 - Regularisation charges - - - 415 - Surety fee - - - 416 - Charges for the deposit of security - - - 418 - Endorsement commission - - - 419 - Bank service fee - - - 420 - Retention charges - - - 425 - Foreign broker's commission - - - 426 - Belgian broker's commission - - - 427 - Belgian Stock Exchange tax - - - 428 - Interest accrued - - - 429 - Foreign Stock Exchange tax - - - 430 - Recovery of foreign tax - - - 431 - Delivery of a copy - - - - diff --git a/addons/l10n_be_coda/l10n_be_coda_trans_code.xml b/addons/l10n_be_coda/l10n_be_coda_trans_code.xml deleted file mode 100644 index b2b23d59bef..00000000000 --- a/addons/l10n_be_coda/l10n_be_coda_trans_code.xml +++ /dev/null @@ -1,1914 +0,0 @@ - - - - - - - 00 - family - Undefined transactions - - - 00 - code - - Undefined transaction - - - 33 - code - - Value correction - - - 35 - code - - Correction - - - 37 - code - - Costs - - - 39 - code - - Cancellation of a transaction - - - 83 - code - - Value correction - - - 85 - code - - Correction - - - 87 - code - - Costs refunded - - - 89 - code - - Cancellation of a transaction - - - 01 - family - Domestic or local SEPA credit transfers - - - 01 - code - - Individual transfer order - Credit transfer given by the customer on paper or electronically, even if the execution date of this transfer is in the future. Domestic payments as well as euro payments meeting the requirements. - - - 02 - code - - Individual transfer order initiated by the bank - The bank takes the initiative for debiting the customer’s account. - - - 03 - code - - Standing order - Credit transfer for which the order has been given once and which is carried out again at regular intervals without any change. - - - 05 - code - - Payment of wages, etc. - The principal will be debited for the total amount of the file entered. - - - 07 - code - - Collective transfer - The principal will be debited for the total amount of the file entered. - - - 09 - code - - Your semi-standing order - - - 11 - code - - Your semi-standing order – payment to employees - - - 13 - code - - Transfer from your account - Transfer from one account to another account of the same customer at the bank's or the customer's initiative (intracompany). - - - 15 - code - - Balance due insurance premium - - - 17 - code - - Financial centralisation - In case of centralisation by the bank, type 2 will be allotted to this transaction. This total can be followed by the detailed movement. - - - 37 - code - - Costs - - - 39 - code - - Your issue circular cheque - To be used for issued circular cheques given in consignment - - - 49 - code - - Cancellation or correction - - - 50 - code - - Transfer in your favour - - - 51 - code - - Transfer in your favour – initiated by the bank - The bank takes the initiative for crediting the customer’s account. - - - 52 - code - - Payment in your favour - Payment by a third person - - - 54 - code - - Unexecutable transfer order - - - 60 - code - - Non-presented circular cheque - - - 62 - code - - Unpaid postal order - - - 64 - code - - Transfer to your account - Intracompany - - - 66 - code - - Financial centralization - In case of centralisation by the bank, type 2 will be allotted to this transaction. This total can be followed by the detailed movement. - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 03 - family - Cheques - - - 01 - code - - Payment of your cheque - - - 03 - code - - Your purchase by payment card - - - 05 - code - - Payment of voucher - Payment of holiday pay, etc. - - - 07 - code - - Definitely unpaid cheque - - - 09 - code - - Unpaid voucher - - - 11 - code - - Department store cheque - - - 13 - code - - Eurocheque written out abroad - - - 15 - code - - Your purchase bank cheque - Cheque drawn by the bank on itself, usually with charges. - - - 17 - code - - Your certified cheque - Amount of the cheque; if any, charges receive code 37 - - - 19 - code - - Settlement of credit cards - - - 35 - code - - Cash advance - - - 37 - code - - Cheque-related costs - - - 38 - code - - Provisionally unpaid - - - 39 - code - - Provisionally unpaid due to other reason than manual presentation - - - 49 - code - - Cancellation or correction - - - 50 - code - - Credit of a payment via terminal - - - 52 - code - - First credit of cheques, vouchers, luncheon vouchers, postal orders, credit under usual reserve - - - 56 - code - - Non-presented certified cheques - - - 58 - code - - Remittance of cheques, vouchers, etc. credit after collection - Also for vouchers, postal orders, anything but bills of exchange, acquittances, promissory notes, etc. - - - 60 - code - - Reversal of voucher - - - 62 - code - - Reversal of cheque - cheques debited on account, but debit cancelled afterwards for lack of cover (double debit/contra-entry of transaction 01 or 05) - - - 63 - code - - Second credit of unpaid cheque - - - 64 - code - - Reversal of settlement of credit card - - - 66 - code - - Remittance of cheque by your branch - credit under usual reserve - - - 68 - code - - Credit of a payment via electronic purse - - - 87 - code - - Reimbursement of cheque-related costs - Overall amount, VAT included - - - 99 - code - - Cancellation or correction - - - 04 - family - Cards - - - 01 - code - - Loading a GSM card - Debit customer who is loading - - - 02 - code - - Payment by means of a payment card within the Eurozone - Eurozone = countries which have the euro as their official currency - - - 03 - code - - Settlement credit cards - See annexe III : communication 124 - - - 04 - code - - Cash withdrawal from an ATM - At home as well as abroad - - - 05 - code - - Loading Proton - - - 06 - code - - Payment with tank card - - - 07 - code - - Payment by GSM - - - 08 - code - - Payment by means of a payment card outside the Eurozone - Eurozone = countries which have the euro as their official currency - - - 37 - code - - Costs - Various costs for possessing or using a payment card - - - 49 - code - - Cancellation or correction - - - 50 - code - - Credit after a payment at a terminal - Except Proton - - - 51 - code - - Unloading Proton - - - 52 - code - - Loading GSM cards - Credit provider - - - 53 - code - - Cash deposit at an ATM - - - 55 - code - - Income from payments by GSM - - - 68 - code - - Credit after Proton payments - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 05 - family - Direct debit - - - 01 - code - - Payment - - - 03 - code - - Unpaid debt - - - 05 - code - - Reimbursement - - - 37 - code - - Costs - - - 49 - code - - Cancellation or correction - - - 50 - code - - Credit after collection - - - 52 - code - - Credit under usual reserve - - - 54 - code - - Reimbursement - - - 56 - code - - Unexecutable reimbursement - - - 58 - code - - Reversal - (cancellation of an undue debit of the debtor at the initiative of the financial institution or the debtor for lack of cover) - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 07 - family - Domestic commercial paper - - - 01 - code - - Payment commercial paper - Bills of exchange, acquittances, promissory notes; debit of the drawee - - - 03 - code - - Payment receipt card - - - 05 - code - - Commercial paper claimed back - Bill claimed back at the drawer's request (bill claimed back before maturity date) - - - 06 - code - - Extension of maturity date - Costs chargeable to the remitter - - - 07 - code - - Unpaid commercial paper - Contra-entry of a direct credit or of a discount - - - 08 - code - - Payment in advance - Debit of the remitter when the drawee pays in advance directly to the remitter (regards bank acceptances) - - - 09 - code - - Agio on supplier's bill - Debit of the agios to the account of the drawee - - - 10 - code - - Renewal of agreed maturity date - - - 12 - code - - Safe custody - - - 14 - code - - Warrant fallen due - - - 37 - code - - Costs related to commercial paper - If any, detail in the category (e.g. costs for presentation for acceptance, etc.) - - - 39 - code - - Return of an irregular bill of exchange - Debit of the drawer after credit under usual reserve or discount - - - 49 - code - - Cancellation or correction - - - 50 - code - - Remittance of commercial paper - credit after collection - Credit of the remitter - - - 52 - code - - Remittance of commercial paper - credit under usual reserve - - - 54 - code - - Remittance of commercial paper for discount - Among other things advances or promissory notes - - - 56 - code - - Remittance of supplier's bill with guarantee - - - 58 - code - - Remittance of supplier's bill without guarantee - - - 64 - code - - Warrant - - - 86 - code - - Payment after cession - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 09 - family - Counter transactions - - - 01 - code - - Cash withdrawal - Withdrawal by counter cheque or receipt; cash remitted by the bank clerk - - - 03 - code - - Cash withdrawal by card (ATM) - - - 05 - code - - Purchase of foreign bank notes - - - 07 - code - - Purchase of gold/pieces - - - 09 - code - - Purchase of petrol coupons - - - 11 - code - - Your purchase of luncheon vouchers - - - 13 - code - - Cash withdrawal by your branch or agents - On the account of the head office - - - 15 - code - - Your purchase of lottery tickets - - - 17 - code - - Purchase of fiscal stamps - - - 19 - code - - Difference in payment - Used in case of payments accepted under reserve of count, result of overcrediting - - - 21 - code - - Cash withdrawal on card (PROTON) - - - 25 - code - - Purchase of traveller’s cheque - - - 37 - code - - Costs - - - 49 - code - - Cancellation or correction - - - 50 - code - - Cash payment - For own account - the comment for the client is given in the communication; also for mixed payments (cash + cheques) - not to be communicated to the clients; for payments made by a third person: see family 01 - - - 52 - code - - Payment night safe - - - 54 - code - - Your payment ATM - - - 56 - code - - Reserve - - - 58 - code - - Payment by your branch/agents - Takes priority over transaction 52 (hence a payment made by an agent in a night safe = 58 and not 52) - - - 60 - code - - Sale of foreign bank notes - - - 62 - code - - Sale of gold/pieces under usual reserve - - - 64 - code - - Your winning lottery ticket - - - 66 - code - - Repurchase of petrol coupons - - - 68 - code - - Difference in payment - In case of payment accepted under reserve of count; result of undercrediting - see also transaction 19 - - - 70 - code - - Sale of traveller’s cheque - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 11 - family - Securities - - - 01 - code - - Purchase of securities - Purchase of domestic or foreign securities, including subscription rights, certificates, etc. - - - 02 - code - - Tenders - Payment to the bank on maturity date - - - 03 - code - - Subscription to securities - Bonds, shares, tap issues of CDs, with or without payment of interest, etc. - - - 04 - code - - Issues - - - 05 - code - - Partial payment subscription - Debit of the subscriber for the complementary payment of partly-paid shares - - - 06 - code - - Share option plan – exercising an option - - - 09 - code - - Settlement of securities - For professionals (stockbrokers) only, whoever the issuer may be (Belgian or foreigner) - - - 11 - code - - Payable coupons/repayable securities - Debit of the issuer by the bank in charge of the financial service - - - 13 - code - - Your repurchase of issue - Unissued part (see 64) - - - 15 - code - - Interim interest on subscription - In case of subscription before the interest due date - - - 17 - code - - Management fee - - - 19 - code - - Regularisation costs - - - 37 - code - - Costs - - - 49 - code - - Cancellation or correction - - - 50 - code - - Sale of securities - - - 51 - code - - Tender - Company issues paper in return for cash - - - 52 - code - - Payment of coupons from a deposit or settlement of coupons delivered over the counter - credit under usual reserve - Whatever the currency of the security - - - 56 - code - - Reserve - - - 58 - code - - Repayable securities from a deposit or delivered at the counter - credit under usual reserve - - - 62 - code - - Interim interest on subscription - When reimbursed separately to the subscriber - - - 64 - code - - Your issue - Amount paid to the issuer by the bank in charge of the placement (firm underwriting or not); also used for the payment in full of partly-paid shares, see transaction 05 - - - 66 - code - - Retrocession of issue commission - For professionals such as insurances and stockbrokers - - - 68 - code - - Compensation for missing coupon - In case coupons attached to a purchased security are missing - - - 70 - code - - Settlement of securities - Only with stockbrokers when they deliver the securities to the bank - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 13 - family - Credit - - - 01 - code - - Short-term loan - Capital and/or interest (specified by the category) - - - 02 - code - - Long-term loan - - - 05 - code - - Settlement of fixed advance - Full or partial reimbursement of a fixed advance at maturity date - - - 07 - code - - Your repayment instalment credits - Often by standing order or direct debit. In case of direct debit, family 13 is used. - - - 11 - code - - Your repayment mortgage loan - - - 13 - code - - Settlement of bank acceptances - - - 15 - code - - Your repayment hire-purchase and similar claims - Hire-purchase agreement under which the financial institution is the lessor - - - 19 - code - - Documentary import credits - - - 21 - code - - Other credit applications - - - 37 - code - - Credit-related costs - - - 49 - code - - Cancellation or correction - - - 50 - code - - Settlement of instalment credit - - - 54 - code - - Fixed advance – capital and interest - - - 55 - code - - Fixed advance – interest only - - - 56 - code - - Subsidy - Interest or capital subsidy - - - 60 - code - - Settlement of mortgage loan - - - 62 - code - - Term loan - - - 68 - code - - Documentary export credits - - - 70 - code - - Settlement of discount bank acceptance - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 30 - family - Various transactions - - - 01 - code - - Spot purchase of foreign exchange - - - 03 - code - - Forward purchase of foreign exchange - - - 05 - code - - Capital and/or interest term investment - - - 33 - code - - Value (date) correction - - - 37 - code - - Costs - - - 39 - code - - Undefined transaction - - - 49 - code - - Cancellation or correction - - - 50 - code - - Spot sale of foreign exchange - - - 52 - code - - Forward sale of foreign exchange - - - 54 - code - - Capital and/or interest term investment - - - 55 - code - - Interest term investment - - - 83 - code - - Value (date) correction - - - 87 - code - - Reimbursement of costs - - - 89 - code - - Undefined transaction - - - 99 - code - - Cancellation or correction - - - 35 - family - Closing (periodical settlements for interest, costs,…) - - - 01 - code - - Closing - - - 37 - code - - Costs - - - 49 - code - - Cancellation or correction - - - 50 - code - - Closing - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 41 - family - International credit transfers - non-SEPA credit transfers - - - 01 - code - - Transfer - - - 03 - code - - Standing order - - - 05 - code - - Collective payments of wages - - - 07 - code - - Collective transfers - - - 13 - code - - Transfer from your account - Intracompany - - - 17 - code - - Financial centralisation (debit) - - - 37 - code - - Costs relating to outgoing foreign transfers and non-SEPA transfers - - - 38 - code - - Costs relating to incoming foreign and non-SEPA transfers - - - 49 - code - - Cancellation or correction - - - 50 - code - - Transfer - - - 64 - code - - Transfer to your account - Intracompany - - - 66 - code - - Financial centralisation (credit) - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 43 - family - Foreign cheques - - - 01 - code - - Payment of a foreign cheque - Debit of a cheque in foreign currency or in EUR in favour of a foreigner - - - 07 - code - - Unpaid foreign cheque - Foreign cheque remitted for collection that returns unpaid - - - 15 - code - - Purchase of an international bank cheque - - - 37 - code - - Costs relating to payment of foreign cheques - - - 49 - code - - Cancellation or correction - - - 52 - code - - Remittance of foreign cheque credit under usual reserve - - - 58 - code - - Remittance of foreign cheque credit after collection - - - 62 - code - - Reversal of cheques - - - 70 - code - - Purchase of traveller’s cheque - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 47 - family - Foreign commercial paper - - - 01 - code - - Payment of foreign bill - - - 05 - code - - Bill claimed back - - - 06 - code - - Extension - - - 07 - code - - Unpaid foreign bill - - - 11 - code - - Payment documents abroad - Bills of lading - - - 13 - code - - Discount foreign supplier's bills - Debit customer, payment of agios, interest, exchange commission, etc. - - - 14 - code - - Warrant fallen due - - - 37 - code - - Costs relating to the payment of a foreign bill - - - 49 - code - - Cancellation or correction - - - 50 - code - - Remittance of foreign bill credit after collection - - - 52 - code - - Remittance of foreign bill credit under usual reserve - - - 54 - code - - Discount abroad - - - 56 - code - - Remittance of guaranteed foreign supplier's bill - - - 58 - code - - Idem without guarantee - - - 60 - code - - Remittance of documents abroad - credit under usual reserve - - - 62 - code - - Remittance of documents abroad - credit after collection - - - 64 - code - - Warrant - - - 87 - code - - Reimbursement of costs - - - 99 - code - - Cancellation or correction - - - 49 - family - Foreign counter transactions - - - 03 - code - - ATM withdrawal - - - 80 - family - Separately charged costs and provisions - - - 01 - code - - Guarantee card charges - - - 02 - code - - Costs relating to electronic output - - - 03 - code - - Payment card charges - - - 04 - code - - Costs for holding a documentary cash credit - - - 05 - code - - Card charges - - - 06 - code - - Damage relating to bills and cheques - - - 07 - code - - Insurance costs - - insurance costs of account holders against fatal accidents - passing-on of several insurance costs - - - 08 - code - - Registering compensation for savings accounts - - - 09 - code - - Postage - Postage recouped to the debit of the customer (including forwarding charges) - - - 10 - code - - Purchase of Smartcard - - - 11 - code - - Costs for the safe custody of correspondence - Costs chargeable to clients who ask to have their correspondence kept at their disposal at the bank's counter - - - 12 - code - - Costs for opening a bank guarantee - - - 13 - code - - Renting of safes - Commission for renting a safe deposit box - - - 14 - code - - Handling costs instalment credit - - - 15 - code - - Night safe - Commission collected to the debit of the customer to whom the bank delivers a key which gives access to the night safe - - - 16 - code - - Bank confirmation to revisor or accountant - - - 17 - code - - Charge for safe custody - Collected for unsealed deposit of securities, and other parcels - - - 18 - code - - Trade information - - - 19 - code - - Special charge for safe custody - Collected for securities, gold, pass-books, etc. placed in safe custody - - - 20 - code - - Drawing up a certificate - - - 21 - code - - Pay-packet charges - Charges for preparing pay packets - - - 22 - code - - Management/custody - - - 23 - code - - Research costs - Costs charged for all kinds of research (information on past transactions, address retrieval, ...) - - - 24 - code - - Participation in and management of interest refund system - - - 25 - code - - Renting of direct debit box - Commission for the renting of boxes put at the disposal for the correspondence - - - 26 - code - - Travel insurance premium - - - 27 - code - - Subscription fee - For publications of the financial institution - - - 29 - code - - Information charges - Charges collected for: - commercial information - sundry information - - - 31 - code - - Writ service fee - E.g. for signing invoices - - - 33 - code - - Miscellaneous fees and commissions - Costs not specified otherwise, often with a manual communication (e.g. for collecting, ordering funds). VAT excluded = type 0 VAT included = type 3 (at least 3 articles) - - - 35 - code - - Costs - Costs charged for calculating the amount of the tax to be paid (e.g. Fiscomat). - - - 37 - code - - Access right to database - Fixed right, either one-off or periodical; for details, see "categories" - - - 39 - code - - Surety fee - Agios on guarantees given - - - 41 - code - - Research costs - - - 43 - code - - Printing of forms - - - 45 - code - - Documentary credit charges - - - 47 - code - - Charging fees for transactions - - - 49 - code - - Cancellation or correction - - - 99 - code - - Cancellation or correction - - - - diff --git a/addons/l10n_be_coda/l10n_be_coda_trans_type.xml b/addons/l10n_be_coda/l10n_be_coda_trans_type.xml deleted file mode 100644 index 9be29ce622a..00000000000 --- a/addons/l10n_be_coda/l10n_be_coda_trans_type.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - 0 - Simple amount without detailed data; e.g. : an individual credit transfer (free of charges). - - - 1 - Amount as totalised by the customer; e.g. a file regrouping payments of wages or payments made to suppliers or a file regrouping collections for which the customer is debited or credited with one single amount. As a matter of principle, this type is also used when no detailed data is following (type 5). - - - 5 - - Detail of 1. Standard procedure is no detailing. However, the customer may ask for detailed data to be included into his file after the overall record (type 1). - - - 2 - Amount as totalised by the bank; e.g. : the total amount of a series of credit transfers with a structured communication As a matter of principle, this type will also be used when no detailed data (type 6 or 7) is following. - - - 6 - - Detail of 2. Simple amount without detailed data. Normally, data of this kind comes after type 2. The customer may ask for a separate file containing the detailed data. In that case, one will speak of a ‘separate application’. The records in a separate application keep type 6. - - - 7 - - Detail of 2. Simple account with detailed data The records in a separate application keep type 7. - - - 9 - - Detail of 7. The records in a separate application keep type 9. - - - 3 - Simple amount with detailed data; e.g. in case of charges for cross-border credit transfers. - - - 8 - - Detail of 3. - - - - diff --git a/addons/l10n_be_coda/l10n_be_coda_view.xml b/addons/l10n_be_coda/l10n_be_coda_view.xml index 1f014400d3c..2464e5e9082 100644 --- a/addons/l10n_be_coda/l10n_be_coda_view.xml +++ b/addons/l10n_be_coda/l10n_be_coda_view.xml @@ -1,510 +1,97 @@ - + + + account.bank.statement.coda.form + account.bank.statement + + + + + + + + + + + bank.statement.line.coda.form + account.bank.statement.line + 10 + +
+ + + + + + + + + + + + + + + +
+ + account.bank.statement.line.coda.tree + account.bank.statement.line + 10 + + + + + + + + + + + + + + + + + + bank.statement.line.coda.filter + account.bank.statement.line + + + + + + + + + + + + + + + + + + + + + + - - + + Bank Statement Lines + account.bank.statement.line + form + tree,form + {'block_statement_line_delete' : 1} + + + - - - coda.bank.account.search - coda.bank.account - - - - - - - - - - - - - - - - - - coda.bank.account.list - coda.bank.account - - - - - - - - - - - - - coda.bank.account.form - coda.bank.account - -
- - - - - - - - - - - - - - - - - - - -
-
-
- - CODA Bank Account Configuration - coda.bank.account - form - tree,form - - - - - - - account.coda.trans.type.tree - account.coda.trans.type - - - - - - - - - - account.coda.trans.type.form - account.coda.trans.type - -
- - - - - -
-
-
- - CODA Transaction Types - ir.actions.act_window - account.coda.trans.type - form - tree,form - - - - - - account.coda.trans.code.tree - account.coda.trans.code - - - - - - - - - - - account.coda.trans.code.form - account.coda.trans.code - -
- - - - - - - - -
-
- - CODA Transaction Codes - ir.actions.act_window - account.coda.trans.code - form - tree,form - - - - - - account.coda.trans.category.tree - account.coda.trans.category - - - - - - - - - account.coda.trans.category.form - account.coda.trans.category - -
- - - - -
- - CODA Transaction Categories - ir.actions.act_window - account.coda.trans.category - form - tree,form - - - - - - account.coda.comm.type.tree - account.coda.comm.type - - - - - - - - - account.coda.comm.type.form - account.coda.comm.type - -
- - - - -
- - CODA Structured Communication Types - ir.actions.act_window - account.coda.comm.type - form - tree,form - - - - - - - - - - account.coda.tree - account.coda - - - - - - - - - - - - - account.coda.form - account.coda - -
- - - - - - - - - - - - - -
-
-
- - - account.coda.search - account.coda - - - - - - - - - - - - - - - - - Imported CODA Files - ir.actions.act_window - account.coda - form - tree,form - - - - - - - - - coda.bank.statement.list - coda.bank.statement - - - - - - - - - - - - - - - - coda.bank.statement.form - coda.bank.statement - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - - coda.bank.statement.search - coda.bank.statement - - - - - - - - - - - - - - - - - - - CODA Bank Statements - ir.actions.act_window - coda.bank.statement - form - tree,form - - - The CODA Bank Statements contain the information encoded in their originating CODA file in a human readable format. The Bank Statements associated with a CODA contain the subset of the CODA Bank Statement data that is required for the creation of the Accounting Entries. - - - - - - - - coda.bank.statement.line.list - coda.bank.statement.line - - - - - - - - - - - - - - - - - - - - - coda.bank.statement.line.form - coda.bank.statement.line - -
- - - - - - - - - - - - - - - - - - -
- - - coda.bank.statement.line.filter - coda.bank.statement.line - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CODA Statement Lines - coda.bank.statement.line - form - tree,form - {'block_statement_line_delete' : 1} - - - - - - - - - - - - -
-
+ + + + \ No newline at end of file diff --git a/addons/l10n_be_coda/l10n_be_coda_wizard.xml b/addons/l10n_be_coda/l10n_be_coda_wizard.xml index 76178820d9c..6e53a4d2ff0 100644 --- a/addons/l10n_be_coda/l10n_be_coda_wizard.xml +++ b/addons/l10n_be_coda/l10n_be_coda_wizard.xml @@ -8,34 +8,14 @@ 1
-
+ + + +
- - - - -
-
- - - - Import CODA File - account.coda.import - 2 - -
-
-
- - - +
@@ -49,20 +29,6 @@ new - - - - diff --git a/addons/l10n_be_coda/security/account_security.xml b/addons/l10n_be_coda/security/account_security.xml deleted file mode 100644 index b8fdd32ebe6..00000000000 --- a/addons/l10n_be_coda/security/account_security.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Account Coda model company rule - - - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] - - - diff --git a/addons/l10n_be_coda/security/ir.model.access.csv b/addons/l10n_be_coda/security/ir.model.access.csv deleted file mode 100644 index 89ee65048fb..00000000000 --- a/addons/l10n_be_coda/security/ir.model.access.csv +++ /dev/null @@ -1,17 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_account_coda_manager,account.coda manager,model_account_coda,account.group_account_manager,1,1,1,1 -access_account_coda_user,account.coda user,model_account_coda,account.group_account_user,1,0,0,0 -access_account_coda_trans_type_manager,account.coda.trans.type manager,model_account_coda_trans_type,account.group_account_manager,1,1,1,1 -access_account_coda_trans_type_user,account.coda.trans.type user,model_account_coda_trans_type,account.group_account_user,1,0,0,0 -access_account_coda_trans_code_manager,account.coda.trans.code manager,model_account_coda_trans_code,account.group_account_manager,1,1,1,1 -access_account_coda_trans_code_user,account.coda.trans.code user,model_account_coda_trans_code,account.group_account_user,1,0,0,0 -access_account_coda_trans_category_manager,account.coda.trans.category manager,model_account_coda_trans_category,account.group_account_manager,1,1,1,1 -access_account_coda_trans_category_user,account.coda.trans.category user,model_account_coda_trans_category,account.group_account_user,1,0,0,0 -access_account_coda_comm_type_manager,account.coda.comm.type manager,model_account_coda_comm_type,account.group_account_manager,1,1,1,1 -access_account_coda_comm_type_user,account.coda.comm.type user,model_account_coda_comm_type,account.group_account_user,1,0,0,0 -access_coda_bank_account_manager,coda.bank.account manager,model_coda_bank_account,account.group_account_manager,1,1,1,1 -access_coda_bank_account_user,coda.bank.account user,model_coda_bank_account,account.group_account_user,1,0,0,0 -access_coda_bank_statement_manager,coda.bank.statement manager,model_coda_bank_statement,account.group_account_manager,1,1,1,1 -access_coda_bank_statement_user,coda.bank.statement user,model_coda_bank_statement,account.group_account_user,1,0,0,0 -access_coda_bank_statement_line_manager,coda.bank.statement.line manager,model_coda_bank_statement_line,account.group_account_manager,1,1,1,1 -access_coda_bank_statement_line_user,coda.bank.statement.line user,model_coda_bank_statement_line,account.group_account_user,1,0,0,0 diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py index da1442312e3..23b2775357c 100644 --- a/addons/l10n_be_coda/wizard/account_coda_import.py +++ b/addons/l10n_be_coda/wizard/account_coda_import.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # -# Copyright (c) 2011 Noviat nv/sa (www.noviat.be). All rights reserved. +# 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 @@ -20,24 +20,22 @@ # ############################################################################## -import time import base64 -from osv import fields,osv +from osv import fields, osv from tools.translate import _ +import time +import tools import logging -import re -from traceback import format_exception -from sys import exc_info -from base_iban import base_iban _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: '', @@ -50,928 +48,338 @@ 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 except: - raise osv.except_osv(_('Error!'), _('Wizard in incorrect state. Please hit the Cancel button.')) + raise osv.except_osv(_('Error'), _('Wizard in incorrect state. Please hit the Cancel button')) return {} - - 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') - trans_category_obj = self.pool.get('account.coda.trans.category') - comm_type_obj = self.pool.get('account.coda.comm.type') - journal_obj = self.pool.get('account.journal') - period_obj = self.pool.get('account.period') - partner_bank_obj = self.pool.get('res.partner.bank') - coda_obj = self.pool.get('account.coda') - coda_st_obj = self.pool.get('coda.bank.statement') - coda_st_line_obj = self.pool.get('coda.bank.statement.line') - bank_st_obj = self.pool.get('account.bank.statement') - 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') - - 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}) - 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) - comm_type_table = comm_type_obj.read(cr, uid, comm_type_obj.search(cr, uid, []), context=context) - - err_string = '' - err_code = None - err_log = '' - coda_statements = [] recordlist = unicode(base64.decodestring(codafile), 'windows-1252', 'strict').split('\n') - + statements = [] for line in recordlist: - if not line: pass elif line[0] == '0': - # start of a new statement within the CODA file - coda_statement = {} - coda_parsing_note = '' - coda_statement_lines = {} - st_line_seq = 0 - glob_lvl_stack = [0] - # header data - coda_statement['currency'] = 'EUR' # default currency - coda_statement['version'] = line[127] - coda_version = line[127] - 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: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - coda_statement['coda_statement_lines'] = {} - coda_statement['date'] = str2date(line[5:11]) - 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 creation date doesn't fall within a defined Accounting Period." \ - "\nPlease create the Accounting Period for date %s.") % coda_statement['date'] - err_code = 'R0002' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - coda_statement['period_id'] = period_id[0] - coda_statement['state'] = 'draft' - - coda_id = coda_obj.search(cr, uid,[ - ('name', '=', codafilename), - ('coda_creation_date', '=', coda_statement['date']), - ]) - if coda_id: - err_string = _("\nCODA File with Filename '%s' and Creation Date '%s' has already been imported.") \ - % (codafilename, coda_statement['date']) - err_code = 'W0001' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Warning!'), err_string) - + #Begin of a new Bank statement + statement = {} + statements.append(statement) + statement['version'] = line[127] + if statement['version'] not in ['1', '2']: + raise osv.except_osv(_('Error') + ' R001', _('CODA V%s statements are not supported, please contact your bank') % statement['version']) + statement['globalisation_stack'] = [] + statement['lines'] = [] + statement['date'] = time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT, time.strptime(rmspaces(line[5:11]), '%d%m%y')) + statement['separateApplication'] = rmspaces(line[83:88]) elif line[0] == '1': - if coda_version == '1': - coda_statement['acc_number'] = line[5:17] - if line[18:21].strip(): - 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] - elif line[1] == '1': # foreign bank account BBAN structure - err_string = _('\nForeign bank accounts with BBAN structure are not supported.') - err_code = 'R1001' - if batch: - 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['currency'] = line[39:42] - elif line[1] == '3': # foreign bank account IBAN structure - err_string = _('\nForeign bank accounts with IBAN structure are not supported.') - err_code = 'R1002' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - else: - err_string = _('\nUnsupported bank account structure.') - err_code = 'R1003' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - coda_statement['description'] = line[90:125].strip() - cba_filter = lambda x: ((coda_statement['acc_number'] in (x['iban'] or '')) or (coda_statement['acc_number'] == x['acc_number'])) \ - and (coda_statement['currency'] == x['currency_name']) and (coda_statement['description'] == (x['description1'] or x['description2'] or '')) - coda_bank = filter(cba_filter, coda_bank_table) - if coda_bank: - 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'] - def_pay_acc = coda_bank['def_payable'][0] - def_rec_acc = coda_bank['def_receivable'][0] - awaiting_acc = coda_bank['awaiting_account'][0] - transfer_acc = coda_bank['transfer_account'][0] - find_bbacom = coda_bank['find_bbacom'] - find_partner = coda_bank['find_partner'] - else: - err_string = _("\nNo matching CODA Bank Account Configuration record found.") + \ - _("\nPlease check if the 'Bank Account Number', 'Currency' and 'Account Description' fields of your configuration record match with '%s', '%s' and '%s'.") \ - % (coda_statement['acc_number'], coda_statement['currency'], coda_statement['description']) - err_code = 'R1004' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - 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['acc_holder'] = line[64:90] - coda_statement['paper_seq_number'] = line[2:5] - coda_statement['coda_seq_number'] = line[125:128] - if coda_bank['coda_st_naming']: - coda_statement['name'] = coda_bank['coda_st_naming'] % { - 'code': coda_bank['journal_code'] or '', - 'year': time.strftime('%Y'), - 'y': time.strftime('%y'), - 'coda': line[125:128], - 'paper': line[2:5], - } - else: - coda_statement['name'] = '/' - - 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['struct_comm_type'] = '' - st_line['struct_comm_type_desc'] = '' - st_line['struct_comm_101'] = '' - st_line['communication'] = '' - st_line['partner_id'] = 0 - st_line['account_id'] = 0 - st_line['counterparty_name'] = '' - st_line['counterparty_bic'] = '' - st_line['counterparty_number'] = '' - 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['trans_ref'] = line[10:31] - st_line_amt = list2float(line[32:47]) - if line[31] == '1': # 1=debit - st_line_amt = - st_line_amt - # 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 - st_line['amount'] = st_line_amt - glob_lvl_stack.pop() + #Statement details + if statement['version'] == '1': + statement['acc_number'] = rmspaces(line[5:17]) + statement['currency'] = rmspaces(line[18:21]) + elif statement['version'] == '2': + if line[1] == '0': # Belgian bank account BBAN structure + statement['acc_number'] = rmspaces(line[5:17]) + statement['currency'] = rmspaces(line[18:21]) + elif line[1] == '1': # foreign bank account BBAN structure + raise osv.except_osv(_('Error') + ' R1001', _('Foreign bank accounts with BBAN structure are not supported ')) + elif line[1] == '2': # Belgian bank account IBAN structure + statement['acc_number'] = rmspaces(line[5:21]) + statement['currency'] = rmspaces(line[39:42]) + elif line[1] == '3': # foreign bank account IBAN structure + raise osv.except_osv(_('Error') + ' R1002', _('Foreign bank accounts with IBAN structure are not supported ')) + else: # Something else, not supported + raise osv.except_osv(_('Error') + ' R1003', _('Unsupported bank account structure ')) + bank_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', statement['acc_number'])]) + not_found_except = osv.except_osv(_('Error') + ' R1004', _("No matching Bank Account.\n\nPlease set-up a Bank Account with as Account Number '%s' and as Currency '%s'.") % (statement['acc_number'], statement['currency'])) + if bank_ids and len(bank_ids) > 0: + bank_accs = self.pool.get('res.partner.bank').browse(cr, uid, bank_ids) + for bank_acc in bank_accs: + if (bank_acc.journal_id.currency and bank_acc.journal_id.currency.name != statement['currency']) and (not bank_acc.journal_id.currency and bank_acc.journal_id.company_id.currency_id.name != statement['currency']): + raise not_found_except else: - glob_lvl_stack.append(glob_lvl_flag) - st_line['type'] = 'globalisation' - st_line['glob_lvl_flag'] = glob_lvl_flag - st_line['globalisation_amount'] = st_line_amt - st_line['account_id'] = None - else: - st_line['amount'] = st_line_amt - # positions 48-53 : Value date or 000000 if not known (DDMMYY) - st_line['val_date'] = str2date(line[47:53]) - # positions 54-61 : transaction code - st_line['trans_type'] = line[53] - 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' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - st_line['trans_type_desc'] = trans_type[0]['description'] - 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) - if not 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) - 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_table) - if trans_code: - st_line['trans_code_desc'] = trans_code[0]['description'] - else: - 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) - if trans_category: - st_line['trans_category_desc'] = trans_category[0]['description'] - else: - st_line['trans_category_desc'] = _('Transaction Category unknown, please consult your bank.') - # positions 61-115 : communication + statement['journal_id'] = bank_acc.journal_id + statement['bank_account'] = bank_acc + break + else: + raise not_found_except + statement['description'] = rmspaces(line[90:125]) + statement['balance_start'] = float(rmspaces(line[43:58])) / 1000 + statement['balance_start_date'] = time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT, time.strptime(rmspaces(line[58:64]), '%d%m%y')) + statement['accountHolder'] = rmspaces(line[64:90]) + statement['paperSeqNumber'] = rmspaces(line[2:5]) + statement['codaSeqNumber'] = rmspaces(line[125:128]) + elif line[0] == '2': + if line[1] == '1': + #New statement line + statementLine = {} + statementLine['ref'] = rmspaces(line[2:10]) + statementLine['ref_move'] = rmspaces(line[2:6]) + statementLine['ref_move_detail'] = rmspaces(line[6:10]) + statementLine['sequence'] = len(statement['lines']) + 1 + statementLine['transactionRef'] = rmspaces(line[10:31]) + statementLine['debit'] = line[31] # 0 = Credit, 1 = Debit + statementLine['amount'] = float(rmspaces(line[32:47])) / 1000 + if statementLine['debit'] == '1': + statementLine['amount'] = - statementLine['amount'] + statementLine['transaction_type'] = line[53] + statementLine['transactionDate'] = time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT, time.strptime(rmspaces(line[47:53]), '%d%m%y')) + statementLine['transaction_family'] = rmspaces(line[54:56]) + statementLine['transaction_code'] = rmspaces(line[56:58]) + statementLine['transaction_category'] = rmspaces(line[58:61]) 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) - if not comm_type: - err_string = _('\nThe File contains an invalid Structured Communication Type : %s.') % st_line['struct_comm_type'] - err_code = 'R2003' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - 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'] == '101': - bbacomm = line[65:77] - st_line['struct_comm_101'] = st_line['name'] = '+++' + bbacomm[0:3] + '/' + bbacomm[3:7] + '/' + bbacomm[7:] + '+++' + #Structured communication + statementLine['communication_struct'] = True + statementLine['communication_type'] = line[62:65] + statementLine['communication'] = '+++' + line[65:68] + '/' + line[68:72] + '/' + line[72:77] + '+++' else: - st_line['communication'] = st_line['name'] = line[62:115] - st_line['entry_date'] = str2date(line[115:121]) - # positions 122-124 not processed - coda_statement_lines[st_line_seq] = st_line - coda_statement['coda_statement_lines'] = coda_statement_lines + #Non-structured communication + statementLine['communication_struct'] = False + statementLine['communication'] = rmspaces(line[62:115]) + statementLine['entryDate'] = time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT, time.strptime(rmspaces(line[115:121]), '%d%m%y')) + statementLine['type'] = 'normal' + statementLine['globalisation'] = int(line[124]) + if len(statement['globalisation_stack']) > 0 and statementLine['communication'] != '': + statementLine['communication'] = "\n".join([statement['globalisation_stack'][-1]['communication'], statementLine['communication']]) + if statementLine['globalisation'] > 0: + if len(statement['globalisation_stack']) > 0 and statement['globalisation_stack'][-1]['globalisation'] == statementLine['globalisation']: + # Destack + statement['globalisation_stack'].pop() + else: + #Stack + statementLine['type'] = 'globalisation' + statement['globalisation_stack'].append(statementLine) + statement['lines'].append(statementLine) elif line[1] == '2': - # movement data record 2.2 - if coda_statement['coda_statement_lines'][st_line_seq]['ref'] != line[2:10]: - err_string = _('\nCODA parsing error on movement data record 2.2, seq nr %s.' \ - '\nPlease report this issue via your OpenERP support channel.') % line[2:10] - err_code = 'R2004' - 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:63] - coda_statement['coda_statement_lines'][st_line_seq]['communication'] += line[10:63] - coda_statement['coda_statement_lines'][st_line_seq]['counterparty_bic'] = line[98:109].strip() + if statement['lines'][-1]['ref'][0:4] != line[2:6]: + raise osv.except_osv(_('Error') + 'R2004', _('CODA parsing error on movement data record 2.2, seq nr %s! Please report this issue via your OpenERP support channel.') % line[2:10]) + statement['lines'][-1]['communication'] += rmspaces(line[10:63]) + statement['lines'][-1]['payment_reference'] = rmspaces(line[63:98]) + statement['lines'][-1]['counterparty_bic'] = rmspaces(line[98:109]) elif line[1] == '3': - # movement data record 2.3 - if coda_statement['coda_statement_lines'][st_line_seq]['ref'] != line[2:10]: - 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] - err_code = 'R2005' - if batch: - return (err_code, 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] - counterparty_name = line[47:125].strip() - counterparty_currency = '' + if statement['lines'][-1]['ref'][0:4] != line[2:6]: + raise osv.except_osv(_('Error') + 'R2005', _('CODA parsing error on movement data record 2.3, seq nr %s! Please report this issue via your OpenERP support channel.') % line[2:10]) + if statement['version'] == '1': + statement['lines'][-1]['counterpartyNumber'] = rmspaces(line[10:22]) + statement['lines'][-1]['counterpartyName'] = rmspaces(line[47:73]) + statement['lines'][-1]['counterpartyAddress'] = rmspaces(line[73:125]) + statement['lines'][-1]['counterpartyCurrency'] = '' else: if line[22] == ' ': - counterparty_number = line[10:22] - counterparty_currency = line[23:26].strip() + statement['lines'][-1]['counterpartyNumber'] = rmspaces(line[10:22]) + statement['lines'][-1]['counterpartyCurrency'] = rmspaces(line[23:26]) else: - counterparty_number = line[10:44].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] - st_line['counterparty_number'] = counterparty_number - st_line['counterparty_currency'] = counterparty_currency - st_line['counterparty_name'] = counterparty_name - 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] - err_code = 'R2006' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Error!'), err_string) - - # partner matching and reconciliation - if st_line['type'] == 'general': - match = False - bank_ids = False - # prepare reconciliation for bba scor - reference = st_line['struct_comm_101'] - if reference and find_bbacom: - inv_ids = inv_obj.search(cr , uid, [('reference' ,'=', reference), ('reference_type' ,'=', 'bba')]) - if inv_ids: - invoice = inv_obj.browse(cr, uid, inv_ids[0]) - partner = invoice.partner_id - st_line['partner_id'] = partner.id - if invoice.type in ['in_invoice', 'in_refund']: - st_line['account_id'] = partner.property_account_payable.id or def_pay_acc - st_line['type'] = 'supplier' - else: - st_line['account_id'] = partner.property_account_receivable.id or def_rec_acc - st_line['type'] = 'customer' - if invoice.type in ['in_invoice', 'out_invoice']: - iml_ids = move_line_obj.search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)]) - if iml_ids: - st_line['reconcile'] = iml_ids[0] - match = True - else: - coda_parsing_note += _("\n Bank Statement '%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.") \ - % (coda_statement['name'], st_line['ref'], reference) - # lookup partner via counterparty_number - if not match and counterparty_number: - cba_filter = lambda x: ((counterparty_number in (x['iban'] or '')) or (counterparty_number == x['acc_number'])) \ - and (x['state'] == 'normal') - transfer_account = filter(cba_filter, coda_bank_table) - if transfer_account: - st_line['account_id'] = transfer_acc - match = True - elif find_partner: - counterparty_number = base_iban._pretty_iban(base_iban._format_iban(counterparty_number)) - bank_ids = partner_bank_obj.search(cr,uid,[('acc_number','=', counterparty_number)]) - if not match and find_partner and bank_ids: - if len(bank_ids) > 1: - coda_parsing_note += _("\n Bank Statement '%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.") \ - % (coda_statement['name'], st_line['ref'], counterparty_number) - else: - bank = partner_bank_obj.browse(cr, uid, bank_ids[0], context) - st_line['partner_id'] = bank.partner_id.id - match = True - if st_line['amount'] < 0: - st_line['account_id'] = bank.partner_id.property_account_payable.id or def_pay_acc - st_line['type'] = 'supplier' - else: - st_line['account_id'] = bank.partner_id.property_account_receivable.id or def_rec_acc - st_line['type'] = 'customer' - elif not match and find_partner: - if counterparty_number: - coda_parsing_note += _("\n Bank Statement '%s' line '%s':" \ - "\n The bank account '%s' is not defined for the partner '%s'." \ - "\n Please correct the configuration and perform the import again or otherwise change the corresponding entry manually in the generated Bank Statement.") \ - % (coda_statement['name'], st_line['ref'], - counterparty_number, counterparty_name) - else: - coda_parsing_note += _("\n Bank Statement '%s' line '%s':" \ - "\n No matching partner record found." \ - "\n Please adjust the corresponding entry manually in the generated Bank Statement.") \ - % (coda_statement['name'], st_line['ref']) - st_line['account_id'] = awaiting_acc - # end of partner record lookup - coda_statement_lines[st_line_seq] = st_line - coda_statement['coda_statement_lines'] = coda_statement_lines + statement['lines'][-1]['counterpartyNumber'] = rmspaces(line[10:44]) + statement['lines'][-1]['counterpartyCurrency'] = rmspaces(line[44:47]) + statement['lines'][-1]['counterpartyName'] = rmspaces(line[47:82]) + statement['lines'][-1]['communication'] += rmspaces(line[82:125]) else: - # movement data record 2.x (x <> 1,2,3) - err_string = _('\nMovement data records of type 2.%s are not supported.') % line[1] - err_code = 'R2007' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - + # movement data record 2.x (x != 1,2,3) + raise osv.except_osv(_('Error') + 'R2006', _('\nMovement data records of type 2.%s are not supported ') % line[1]) 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['struct_comm_type'] = '' - info_line['struct_comm_type_desc'] = '' - info_line['communication'] = '' - info_line['ref'] = line[2:10] - 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) - 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'] - 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) - if not 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) - 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']), - 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) - 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 - 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) - if not comm_type: - err_string = _('\nThe File contains an invalid Structured Communication Type : %s.') % info_line['struct_comm_type'] - err_code = 'R3003' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('Data Error!'), err_string) - info_line['struct_comm_type_desc'] = comm_type[0]['description'] - info_line['communication'] = info_line['name'] = line[43:113] - else: - info_line['communication'] = info_line['name'] = line[40:113] - # positions 114-128 not processed - coda_statement_lines[st_line_seq] = info_line - coda_statement['coda_statement_lines'] = coda_statement_lines + infoLine = {} + infoLine['entryDate'] = statement['lines'][-1]['entryDate'] + infoLine['type'] = 'information' + infoLine['sequence'] = len(statement['lines']) + 1 + infoLine['ref'] = rmspaces(line[2:10]) + infoLine['transactionRef'] = rmspaces(line[10:31]) + infoLine['transaction_type'] = line[31] + infoLine['transaction_family'] = rmspaces(line[32:34]) + infoLine['transaction_code'] = rmspaces(line[34:36]) + infoLine['transaction_category'] = rmspaces(line[36:39]) + infoLine['communication'] = rmspaces(line[40:113]) + statement['lines'].append(infoLine) elif line[1] == '2': - # information data record 3.2 - if coda_statement['coda_statement_lines'][st_line_seq]['ref'] != line[2:10]: - err_string = _('\nCODA parsing error on information data record 3.2, seq nr %s.' \ - '\nPlease report this issue via your OpenERP support channel.') % line[2:10] - err_code = 'R3004' - 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]['communication'] += line[10:115] + if infoLine['ref'] != rmspaces(line[2:10]): + raise osv.except_osv(_('Error') + 'R3004', _('CODA parsing error on information data record 3.2, seq nr %s! Please report this issue via your OpenERP support channel.') % line[2:10]) + statement['lines'][-1]['communication'] += rmspaces(line[10:100]) elif line[1] == '3': - # information data record 3.3 - if coda_statement['coda_statement_lines'][st_line_seq]['ref'] != line[2:10]: - err_string = _('\nCODA parsing error on information data record 3.3, seq nr %s.' \ - '\nPlease report this issue via your OpenERP support channel.') % line[2:10] - err_code = 'R3005' - 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:100] - coda_statement['coda_statement_lines'][st_line_seq]['communication'] += line[10:100] - + if infoLine['ref'] != rmspaces(line[2:10]): + raise osv.except_osv(_('Error') + 'R3005', _('CODA parsing error on information data record 3.3, seq nr %s! Please report this issue via your OpenERP support channel.') % line[2:10]) + statement['lines'][-1]['communication'] += rmspaces(line[10:100]) elif line[0] == '4': - # free communication data record 4 - comm_line = {} - comm_line['type'] = 'communication' - st_line_seq = st_line_seq + 1 - comm_line['sequence'] = st_line_seq - comm_line['ref'] = line[2:10] - 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 - + comm_line = {} + comm_line['type'] = 'communication' + comm_line['sequence'] = len(statement['lines']) + 1 + comm_line['ref'] = rmspaces(line[2:10]) + comm_line['communication'] = rmspaces(line[32:112]) + statement['lines'].append(comm_line) elif line[0] == '8': # new balance record - bal_end = list2float(line[42:57]) - if line[41] == '1': # 1=Debit - bal_end = - bal_end - coda_statement['balance_end_real'] = bal_end - + statement['debit'] = line[41] + statement['paperSeqNumber'] = rmspaces(line[1:4]) + statement['balance_end_real'] = float(rmspaces(line[42:57])) / 1000 + statement['balance_end_realDate'] = time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT, time.strptime(rmspaces(line[57:63]), '%d%m%y')) + if statement['debit'] == '1': # 1=Debit + statement['balance_end_real'] = - statement['balance_end_real'] + if statement['balance_end_realDate']: + period_id = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', statement['balance_end_realDate']), ('date_stop', '>=', statement['balance_end_realDate'])]) + else: + period_id = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', statement['date']), ('date_stop', '>=', statement['date'])]) + if not period_id and len(period_id) == 0: + raise osv.except_osv(_('Error') + 'R0002', _("The CODA Statement New Balance date doesn't fall within a defined Accounting Period! Please create the Accounting Period for date %s.") % statement['balance_end_realDate']) + statement['period_id'] = period_id[0] elif line[0] == '9': - # footer record - 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: - coda_statement['coda_parsing_note'] = '\nStatement Line matching results:' + coda_parsing_note + statement['balanceMin'] = float(rmspaces(line[22:37])) / 1000 + statement['balancePlus'] = float(rmspaces(line[37:52])) / 1000 + if not statement['balance_end_real']: + statement['balance_end_real'] = statement['balance_start'] + statement['balancePlus'] - statement['balanceMin'] + for i, statement in enumerate(statements): + statement['coda_note'] = '' + balance_start_check_date = (len(statement['lines']) > 0 and statement['lines'][0]['entryDate']) or statement['date'] + cr.execute('SELECT balance_end_real \ + FROM account_bank_statement \ + WHERE journal_id = %s and date <= %s \ + ORDER BY date DESC,id DESC LIMIT 1', (statement['journal_id'].id, balance_start_check_date)) + res = cr.fetchone() + balance_start_check = res and res[0] + if balance_start_check == None: + if statement['journal_id'].default_debit_account_id and (statement['journal_id'].default_credit_account_id == statement['journal_id'].default_debit_account_id): + balance_start_check = statement['journal_id'].default_debit_account_id.balance else: - coda_statement['coda_parsing_note'] = '' - coda_statements.append(coda_statement) - #end for + raise osv.except_osv(_('Error'), _("Configuration Error in journal %s!\nPlease verify the Default Debit and Credit Account settings.") % statement['journal_id'].name) + if balance_start_check != statement['balance_start']: + statement['coda_note'] = _("The CODA Statement %s Starting Balance (%.2f) does not correspond with the previous Closing Balance (%.2f) in journal %s!") % (statement['description'] + ' #' + statement['paperSeqNumber'], statement['balance_start'], balance_start_check, statement['journal_id'].name) + data = { + 'name': '[' + statement['date'] + ']' + statement['description'], + 'date': statement['date'], + 'journal_id': statement['journal_id'].id, + 'period_id': statement['period_id'], + 'balance_start': statement['balance_start'], + 'balance_end_real': statement['balance_end_real'], + } + statement['id'] = self.pool.get('account.bank.statement').create(cr, uid, data, context=context) + for line in statement['lines']: + if line['type'] == 'information': + statement['coda_note'] = "\n".join([statement['coda_note'], line['type'].title() + ' with Ref. ' + str(line['ref']), 'Date: ' + str(line['entryDate']), 'Communication: ' + line['communication'], '']) + elif line['type'] == 'communication': + statement['coda_note'] = "\n".join([statement['coda_note'], line['type'].title() + ' with Ref. ' + str(line['ref']), 'Ref: ', 'Communication: ' + line['communication'], '']) + elif line['type'] == 'normal': + note = [] + if 'counterpartyName' in line and line['counterpartyName'] != '': + note.append(_('Counter Party') + ': ' + line['counterpartyName']) + else: + line['counterpartyName'] = False + if 'counterpartyNumber' in line and line['counterpartyNumber'] != '': + try: + if int(line['counterpartyNumber']) == 0: + line['counterpartyNumber'] = False + except: + pass + if line['counterpartyNumber']: + note.append(_('Counter Party Account') + ': ' + line['counterpartyNumber']) + else: + line['counterpartyNumber'] = False - err_string = '' - err_code = '' - coda_id = 0 - coda_note = '' - line_note = '' - - try: - coda_id = coda_obj.create(cr, uid,{ - 'name' : codafilename, - 'coda_data': codafile, - '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 : - cr.rollback() - err_string = _('\nUnknown Error : ') + str(e) - if err_string: - err_code = 'G0001' - if batch: - return (err_code, err_string) - raise osv.except_osv(_('CODA Import failed.'), err_string) - - nb_err = 0 - err_string = '' - coda_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: - - 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'], - 'journal_id': statement['journal_id'], - 'coda_id': coda_id, - 'date': statement['date'], - 'period_id': statement['period_id'], - 'balance_start': statement['balance_start'], - 'balance_end_real': statement['balance_end_real'], - 'state':'draft', - }) - coda_st_ids.append(coda_st_id) - - if statement['type'] == 'normal': - context.update({'ebanking_import': 1}) - journal = journal_obj.browse(cr, uid, statement['journal_id'], context=context) - cr.execute('SELECT balance_end_real \ - FROM account_bank_statement \ - WHERE journal_id = %s and date < %s \ - ORDER BY date DESC,id DESC LIMIT 1', (statement['journal_id'], statement['date'])) - res = cr.fetchone() - balance_start_check = res and res[0] - if balance_start_check == None: - 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 + if 'counterpartyAddress' in line and line['counterpartyAddress'] != '': + note.append(_('Counter Party Address') + ': ' + line['counterpartyAddress']) + line['name'] = "\n".join(filter(None, [line['counterpartyName'], line['communication']])) + line['transaction_type'] = 'general' + partner = None + partner_id = None + invoice = False + if line['communication_struct'] and 'communication_type' in line and line['communication_type'] == '101': + ids = self.pool.get('account.invoice').search(cr, uid, [('reference', '=', line['communication']), ('reference_type', '=', 'bba')]) + if ids: + invoice = self.pool.get('account.invoice').browse(cr, uid, ids[0]) + partner = invoice.partner_id + partner_id = partner.id + if invoice.type in ['in_invoice', 'in_refund'] and line['debit'] == '1': + line['transaction_type'] = 'supplier' + elif invoice.type in ['out_invoice', 'out_refund'] and line['debit'] == '0': + line['transaction_type'] = 'customer' + line['account'] = invoice.account_id.id + line['reconcile'] = False + if invoice.type in ['in_invoice', 'out_invoice']: + iml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)]) + if iml_ids: + line['reconcile'] = iml_ids[0] + if line['reconcile']: + voucher_vals = { + 'type': line['transaction_type'] == 'supplier' and 'payment' or 'receipt', + 'name': line['name'], + 'partner_id': partner_id, + 'journal_id': statement['journal_id'].id, + 'account_id': statement['journal_id'].default_credit_account_id.id, + 'company_id': statement['journal_id'].company_id.id, + 'currency_id': statement['journal_id'].company_id.currency_id.id, + 'date': line['entryDate'], + 'amount': abs(line['amount']), + 'period_id': statement['period_id'], + 'invoice_id': invoice.id, + } + context['invoice_id'] = invoice.id + voucher_vals.update(self.pool.get('account.voucher').onchange_partner_id(cr, uid, [], + partner_id=partner_id, + journal_id=statement['journal_id'].id, + amount=abs(line['amount']), + currency_id=statement['journal_id'].company_id.currency_id.id, + ttype=line['transaction_type'] == 'supplier' and 'payment' or 'receipt', + date=line['transactionDate'], + context=context + )['value']) + line_drs = [] + for line_dr in voucher_vals['line_dr_ids']: + line_drs.append((0, 0, line_dr)) + voucher_vals['line_dr_ids'] = line_drs + line_crs = [] + for line_cr in voucher_vals['line_cr_ids']: + line_crs.append((0, 0, line_cr)) + voucher_vals['line_cr_ids'] = line_crs + line['voucher_id'] = self.pool.get('account.voucher').create(cr, uid, voucher_vals, context=context) + if 'counterpartyNumber' in line and line['counterpartyNumber']: + ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', str(line['counterpartyNumber']))]) + if ids and len(ids) > 0: + partner = self.pool.get('res.partner.bank').browse(cr, uid, ids[0], context=context).partner_id + partner_id = partner.id + if not invoice: + if line['debit'] == '0': + line['account'] = partner.property_account_receivable.id + if partner.customer: + line['transaction_type'] = 'customer' + elif line['debit'] == '1': + line['account'] = partner.property_account_payable.id + if partner.supplier: + line['transaction_type'] = 'supplier' + if not partner and not invoice: + if line['debit'] == '1': + line['account'] = statement['journal_id'].default_debit_account_id.id else: - nb_err += 1 - err_string += _('\nConfiguration Error!\nPlease verify the Default Debit and Credit Account settings in journal %s.') % journal.name - break - bk_st_id = bank_st_obj.create(cr, uid, { - 'name': statement['name'], - 'journal_id': statement['journal_id'], - 'coda_statement_id': coda_st_id, - 'date': statement['date'], - 'period_id': statement['period_id'], - 'balance_start': statement['balance_start'], - 'balance_end_real': statement['balance_end_real'], - 'state': 'draft', - }) - bk_st_ids.append(bk_st_id) - coda_st_obj.write(cr, uid, [coda_st_id], {'statement_id': bk_st_id}, context=context) - - glob_id_stack = [(0, '', 0, '')] # stack with tuples (glob_lvl_flag, glob_code, glob_id, glob_name) - lines = statement['coda_statement_lines'] - st_line_seq = 0 - - for x in lines: - line = lines[x] - - # handling non-transactional records : line['type'] in ['information', 'communication'] - - if line['type'] == 'information': - - 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_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, { - 'sequence': line['sequence'], - 'ref': line['ref'], - 'name': line['name'].strip() or '/', - '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, { - 'sequence': line['sequence'], - 'ref': line['ref'], - 'name': line['name'].strip() or '/', - 'type' : 'communication', - 'date': statement['date'], - 'statement_id': coda_st_id, - 'note': line_note, - }) - - # handling transactional records, # line['type'] in ['globalisation', 'general', 'supplier', 'customer'] - - else: - - glob_lvl_flag = line['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, - 'name': glob_name, - 'type': 'coda', - 'parent_id': glob_id_stack[-1][2], - 'amount': line['globalisation_amount'], - }) - 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' \ - '\nTransaction Code: %s - %s' \ - '\nTransaction Category: %s - %s' \ - '\nStructured Communication Type: %s - %s' \ - '\nCommunication: %s') \ - %(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['communication']) - - if line['type'] == 'globalisation': - - coda_st_line_id = coda_st_line_obj.create(cr, uid, { - 'sequence': line['sequence'], - 'ref': line['ref'], - 'name': line['name'].strip() or '/', - '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'], - 'partner_id': line['partner_id'] or 0, - 'account_id': line['account_id'], - 'statement_id': coda_st_id, - 'note': line_note, - }) - - else: # line['type'] in ['general', 'supplier', 'customer'] - - if glob_lvl_flag == 0: - line['globalisation_id'] = glob_id_stack[-1][2] - if not line['account_id']: - line['account_id'] = awaiting_acc - - coda_st_line_id = coda_st_line_obj.create(cr, uid, { - 'sequence': line['sequence'], - 'ref': line['ref'], - 'name': line['name'] 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'], - 'account_id': line['account_id'], - 'globalisation_level': line['glob_lvl_flag'], - 'globalisation_id': line['globalisation_id'], - 'statement_id': coda_st_id, - 'note': line_note, - }) - - if statement['type'] == 'normal': - - st_line_seq += 1 - voucher_id = False - line_name = line['name'].strip() - if not line_name: - if line['globalisation_id']: - line_name = glob_id_stack[-1][3] - else: - line_name = '/' - - if line['reconcile']: - voucher_vals = { - 'type': line['type'] == 'supplier' and 'payment' or 'receipt', - 'name': line_name, - 'partner_id': line['partner_id'], - 'journal_id': statement['journal_id'], - 'account_id': journal.default_credit_account_id.id, - 'company_id': journal.company_id.id, - 'currency_id': journal.company_id.currency_id.id, - 'date': line['entry_date'], - 'amount': abs(line['amount']), - 'period_id': statement['period_id'], - } - voucher_id = voucher_obj.create(cr, uid, voucher_vals, context=context) - - move_line = move_line_obj.browse(cr, uid, line['reconcile'], context=context) - voucher_dict = voucher_obj.onchange_partner_id(cr, uid, [], - partner_id = line['partner_id'], - journal_id = statement['journal_id'], - price = abs(line['amount']), - currency_id = journal.company_id.currency_id.id, - ttype = line['type'] == 'supplier' and 'payment' or 'receipt', - date = line['val_date'], - context = context) - #_logger.warning('voucher_dict = %s' % voucher_dict) - voucher_line_vals = False - if voucher_dict['value']['line_ids']: - for line_dict in voucher_dict['value']['line_ids']: - if line_dict['move_line_id'] == move_line.id: - voucher_line_vals = line_dict - if voucher_line_vals: - voucher_line_vals.update({ - 'voucher_id': voucher_id, - 'amount': abs(line['amount']), - }) - voucher_line_obj.create(cr, uid, voucher_line_vals, context=context) - - bank_st_line_id = bank_st_line_obj.create(cr, uid, { - 'sequence': st_line_seq, - 'ref': line['ref'], - 'name': line_name, - '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'], - 'account_id': line['account_id'], - 'globalisation_id': line['globalisation_id'], - 'statement_id': bk_st_id, - 'voucher_id': voucher_id, - 'note': line_note, - }) - # end 'for x in lines' - - 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']: - 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': - nb_err += 1 - 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 - journal_name = journal.name - else: - journal_name = _('None') - coda_note = coda_note + \ - _('\n\nBank Journal: %s' \ - '\nCODA Version: %s' \ - '\nCODA Sequence Number: %s' \ - '\nPaper Statement Sequence Number: %s' \ - '\nBank Account: %s' \ - '\nAccount Holder Name: %s' \ - '\nDate: %s, Starting Balance: %.2f, Ending Balance: %.2f' \ - '%s') \ - %(journal_name, - coda_version, - statement['coda_seq_number'], - statement['paper_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']) - - except osv.except_osv, e: - cr.rollback() - nb_err += 1 - err_string += _('\nError ! ') + str(e) - tb = ''.join(format_exception(*exc_info())) - _logger.error('Application Error while processing Statement %s\n%s' % (statement.get('name', '/'),tb)) - except Exception, e: - cr.rollback() - 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 : - 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)) - - # 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 }) - cr.commit() - if batch: - return None - else: - cr.rollback() - if batch: - 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}) - 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) - + line['account'] = statement['journal_id'].default_credit_account_id.id + if 'communication' in line and line['communication'] != '': + note.append(_('Communication') + ': ' + line['communication']) + if 'voucher_id' not in line: + line['voucher_id'] = None + data = { + 'name': line['name'], + 'note': "\n".join(note), + 'date': line['entryDate'], + 'amount': line['amount'], + 'type': line['transaction_type'], + 'partner_id': partner_id, + 'account_id': line['account'], + 'statement_id': statement['id'], + 'ref': line['ref'], + 'sequence': line['sequence'], + 'voucher_id': line['voucher_id'], + 'coda_account_number': line['counterpartyNumber'], + } + self.pool.get('account.bank.statement.line').create(cr, uid, data, context=context) + if statement['coda_note'] != '': + self.pool.get('account.bank.statement').write(cr, uid, [statement['id']], {'coda_note': statement['coda_note']}, context=context) return { - 'name': _('Import CODA File result'), - 'res_id': ids[0], 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'account.coda.import', + 'view_mode': 'tree,form', + 'res_model': 'account.bank.statement', 'view_id': False, - 'target': 'new', - 'views': [(resource_id, 'form')], 'context': context, 'type': 'ir.actions.act_window', } - def action_open_coda_statements(self, cr, uid, ids, context=None): - if context is None: - context = {} - module, xml_id = 'l10n_be_coda', 'action_coda_bank_statements' - 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 += [('coda_id', '=', context.get('coda_id', False))] - action.update({'domain': domain}) - return action - def action_open_bank_statements(self, cr, uid, ids, context=None): - if context is None: - context = {} - module, xml_id = 'account', 'action_bank_statement_tree' - 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))] - action.update({'domain': domain}) - return action +def rmspaces(s): + return " ".join(s.split()) -account_coda_import() -def str2date(date_str): - return time.strftime('%Y-%m-%d', time.strptime(date_str,'%d%m%y')) - -def str2float(str): - try: - return float(str) - except: - return 0.0 - -def list2float(lst): - try: - return str2float((lambda s : s[:-3] + '.' + s[-3:])(lst)) - except: - return 0.0 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: