[merge] [IMP] account_statement_base_import: Added some function to be able to fill the balance, the name and the date of the bank statement based on the data of the file parsed.

mirrors closely the approach for statement lines (get_st_line_vals) with the same approch for the statement (get_st_vals)
This commit is contained in:
Laurent Mignon (Acsone)
2014-01-21 17:46:36 +01:00
19 changed files with 470 additions and 66 deletions

View File

@@ -35,7 +35,6 @@
1) Match from statement line label (based on partner field 'Bank Statement Label')
2) Match from statement line label (based on partner name)
3) Match from statement line reference (based on SO number)
3) Match from statement line reference (based on Invoice number)
You can easily override this module and add your own rules in your own one. The basic rules only
@@ -58,15 +57,19 @@
""",
'website': 'http://www.camptocamp.com',
'init_xml': [],
'update_xml': [
'data': [
'statement_view.xml',
'partner_view.xml',
'data.xml',
'security/ir.model.access.csv',
],
'demo_xml': [],
'test': [],
'demo': [],
'test': [
'test/partner.yml',
'test/invoice.yml',
'test/supplier_invoice.yml',
'test/completion_test.yml'
],
'installable': True,
'images': [],
'auto_install': False,

View File

@@ -14,12 +14,6 @@
<field name="function_to_call">get_from_label_and_partner_name</field>
</record>
<record id="bank_statement_completion_rule_1" model="account.statement.completion.rule">
<field name="name">Match from line reference (based on SO number)</field>
<field name="sequence">50</field>
<field name="function_to_call">get_from_ref_and_so</field>
</record>
<record id="bank_statement_completion_rule_4" model="account.statement.completion.rule">
<field name="name">Match from line reference (based on Invoice number)</field>
<field name="sequence">40</field>

View File

@@ -132,7 +132,6 @@ class AccountStatementCompletionRule(orm.Model):
return [
('get_from_ref_and_invoice', 'From line reference (based on customer invoice number)'),
('get_from_ref_and_supplier_invoice', 'From line reference (based on supplier invoice number)'),
('get_from_ref_and_so', 'From line reference (based on SO number)'),
('get_from_label_and_partner_field', 'From line label (based on partner field)'),
('get_from_label_and_partner_name', 'From line label (based on partner name)')]
@@ -232,49 +231,6 @@ class AccountStatementCompletionRule(orm.Model):
"""
return self._from_invoice(cr, uid, line, 'customer', context=context)
# Should be private but data are initialised with no update XML
def get_from_ref_and_so(self, cr, uid, st_line, context=None):
"""
Match the partner based on the SO number and the reference of the statement
line. Then, call the generic get_values_for_line method to complete other values.
If more than one partner matched, raise the ErrorTooManyPartner error.
:param int/long st_line: read of the concerned account.bank.statement.line
:return:
A dict of value that can be passed directly to the write method of
the statement line or {}
{'partner_id': value,
'account_id': value,
...}
"""
st_obj = self.pool.get('account.bank.statement.line')
res = {}
if st_line:
so_obj = self.pool.get('sale.order')
so_id = so_obj.search(cr,
uid,
[('name', '=', st_line['ref'])],
context=context)
if so_id:
if so_id and len(so_id) == 1:
so = so_obj.browse(cr, uid, so_id[0], context=context)
res['partner_id'] = so.partner_id.id
elif so_id and len(so_id) > 1:
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more '
'than one partner while looking on SO by ref.') %
(st_line['name'], st_line['ref']))
st_vals = st_obj.get_values_for_line(cr,
uid,
profile_id=st_line['profile_id'],
master_account_id=st_line['master_account_id'],
partner_id=res.get('partner_id', False),
line_type='customer',
amount=st_line['amount'] if st_line['amount'] else 0.0,
context=context)
res.update(st_vals)
return res
# Should be private but data are initialised with no update XML
def get_from_label_and_partner_field(self, cr, uid, st_line, context=None):
"""

View File

@@ -0,0 +1,87 @@
-
In order to test the banking framework, I first need to create a profile
-
!record {model: account.statement.profile, id: profile_test1}:
name: Bank EUR Profile
journal_id: account.bank_journal
commission_account_id: account.a_expense
company_id: base.main_company
balance_check: True
rule_ids:
- bank_statement_completion_rule_4
- bank_statement_completion_rule_5
- bank_statement_completion_rule_2
- bank_statement_completion_rule_3
-
Now I create a statement. I create statment lines separately because I need
to find each one by XML id
-
!record {model: account.bank.statement, id: statement_test1}:
name: Statement 2
profile_id: profile_test1
company_id: base.main_company
-
I create a statement line for a CI
-
!record {model: account.bank.statement.line, id: statement_line_ci}:
name: Test autocompletion based on Customer Invoice Number
statement_id: statement_test1
ref: CI0001
date: '2013-12-20'
amount: 210.0
-
I create a statement line for a SI
-
!record {model: account.bank.statement.line, id: statement_line_si}:
name: Test autocompletion based on Supplier Invoice Number
statement_id: statement_test1
ref: T2S12345
date: '2013-12-19'
amount: -65.0
-
I create a statement line for the Partner Name
-
!record {model: account.bank.statement.line, id: statement_line_partner_name}:
name: Test autocompletion based on Partner Name Vauxoo
statement_id: statement_test1
ref: /
date: '2013-12-17'
amount: 600.0
-
I create a statement line for the Partner Label
-
!record {model: account.bank.statement.line, id: statement_line_partner_label}:
name: test autocompletion based on text (XXX66Z) matching with partner form information (note that Ref does not exist)
statement_id: statement_test1
ref: ZU788
date: '2013-12-24'
amount: -932.4
-
I run the auto complete
-
!python {model: account.bank.statement}: |
result = self.button_auto_completion(cr, uid, [ref("statement_test1")])
-
Now I can check that all is nice and shiny, line 1. I expect the Customer
Invoice Number to be recognised.
I Use _ref, because ref conflicts with the field ref of the statement line
-
!assert {model: account.bank.statement.line, id: statement_line_ci, string: Check completion by CI number}:
- partner_id.id == _ref("base.res_partner_12")
-
Line 2. I expect the Supplier invoice number to be recognised. The supplier
invoice was created by the account module demo data, and we confirmed it
here.
-
!assert {model: account.bank.statement.line, id: statement_line_si, string: Check completion by SI number}:
- partner_id.id == _ref("base.res_partner_17")
-
Line 3. I check that the partner name has been recognised.
-
!assert {model: account.bank.statement.line, id: statement_line_partner_name, string: Check completion by partner name}:
- partner_id.name == 'Vauxoo'
-
Line 4. I check that the partner special label has been recognised.
-
!assert {model: account.bank.statement.line, id: statement_line_partner_label, string: Check completion by partner label}:
- partner_id.id == _ref("base.res_partner_6")

View File

@@ -0,0 +1,32 @@
-
I create a customer Invoice to be found by the completion.
-
!record {model: account.invoice, id: invoice_for_completion_1}:
account_id: account.a_recv
company_id: base.main_company
currency_id: base.EUR
internal_number: CI0001
invoice_line:
- account_id: account.a_sale
name: '[PCSC234] PC Assemble SC234'
price_unit: 210.0
quantity: 1.0
product_id: product.product_product_3
uos_id: product.product_uom_unit
journal_id: account.bank_journal
partner_id: base.res_partner_12
reference_type: none
-
I confirm the Invoice
-
!workflow {model: account.invoice, action: invoice_open, ref: invoice_for_completion_1}
-
I check that the invoice state is "Open"
-
!assert {model: account.invoice, id: invoice_for_completion_1}:
- state == 'open'
-
I check that it is given the number "CI0001"
-
!assert {model: account.invoice, id: invoice_for_completion_1, string: Check CI number}:
- number == 'CI0001'

View File

@@ -0,0 +1,5 @@
-
I fill in the field Bank Statement Label in a Partner
-
!record {model: res.partner, id: base.res_partner_6}:
bank_statement_label: XXX66Z

View File

@@ -0,0 +1,31 @@
-
I check that my invoice is a supplier invoice
-
!assert {model: account.invoice, id: account.demo_invoice_0, string: Check invoice type}:
- type == 'in_invoice'
-
I add a reference to an existing supplier invoce
-
!python {model: account.invoice}: |
self.write(cr, uid, ref('account.demo_invoice_0'), {
'supplier_invoice_number': 'T2S12345'
})
-
I check a second time that my invoice is still a supplier invoice
-
!assert {model: account.invoice, id: account.demo_invoice_0, string: Check invoice type 2}:
- type == 'in_invoice'
-
Now I confirm it
-
!workflow {model: account.invoice, action: invoice_open, ref: account.demo_invoice_0}
-
I check that the supplier number is there
-
!assert {model: account.invoice, id: account.demo_invoice_0, string: Check supplier number}:
- supplier_invoice_number == 'T2S12345'
-
I check a third time that my invoice is still a supplier invoice
-
!assert {model: account.invoice, id: account.demo_invoice_0, string: Check invoice type 3}:
- type == 'in_invoice'

View File

@@ -49,6 +49,10 @@ class BankStatementImportParser(object):
self.result_row_list = None
# The file buffer on which to work on
self.filebuffer = None
self.balance_start = None
self.balance_end = None
self.statement_name = None
self.statement_date = None
@classmethod
def parser_for(cls, parser_name):
@@ -116,7 +120,12 @@ class BankStatementImportParser(object):
create method of statement.
:return: dict of vals that represent additional infos for the statement
"""
return {}
return {
'name': self.statement_name,
'balance_start': self.balance_start,
'balance_end_real': self.balance_end,
'date': self.statement_date
}
def get_st_line_vals(self, line, *args, **kwargs):
"""

View File

@@ -97,6 +97,7 @@ class CreditPartnerStatementImporter(orm.TransientModel):
req_id = req_id[0]
importer = self.browse(cr, uid, req_id, context)
ftype = self._check_extension(importer.file_name)
context['file_name'] = importer.file_name
sid = self.pool.get(
'account.statement.profile').statement_import(
cr,

View File

@@ -22,7 +22,7 @@ class AccountStatementProfil(orm.Model):
commission_analytic_id = profile.commission_analytic_id and profile.commission_analytic_id.id or False
comm_values = {
'name': 'IN ' + _('Commission line'),
'date': datetime.datetime.now().date(),
'date': parser.get_st_vals().get('date') or datetime.datetime.now(),
'amount': global_commission_amount,
'partner_id': partner_id,
'type': 'general',

View File

@@ -223,12 +223,17 @@ class AccountBankSatement(Model):
move of period_id to the statement line
"""
for statement in self.browse(cr, uid, ids, context=context):
# statement.company_id is a related store=True that for some
# reason doesn't work in YAML tests. As a workaround, I unwind it
# to statement.journal_id.company_id here.
if (statement.period_id and
statement.company_id.id != statement.period_id.company_id.id):
statement.journal_id.company_id.id !=
statement.period_id.company_id.id):
return False
for line in statement.line_ids:
if (line.period_id and
statement.company_id.id != line.period_id.company_id.id):
statement.journal_id.company_id.id
!= line.period_id.company_id.id):
return False
return True
@@ -552,12 +557,8 @@ class AccountBankSatement(Model):
import_config = self.pool.get("account.statement.profile").browse(
cr, uid, profile_id, context=context)
journal_id = import_config.journal_id.id
account_id = import_config.journal_id.default_debit_account_id.id
credit_partner_id = import_config.partner_id and import_config.partner_id.id or False
return {'value': {'journal_id': journal_id,
'account_id': account_id,
'balance_check': import_config.balance_check,
'credit_partner_id': credit_partner_id}}
'balance_check': import_config.balance_check}}
class AccountBankSatementLine(Model):

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
###############################################################################
# #
# Author: Joel Grand-Guillaume
# Copyright 2011-2012 Camptocamp SA
# #
# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
# Copyright 2013 Camptocamp SA #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU Affero General Public License as #
# published by the Free Software Foundation, either version 3 of the #
# License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU Affero General Public License for more details. #
# #
# You should have received a copy of the GNU Affero General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
from . import statement

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
###############################################################################
# #
# Author: Joel Grand-Guillaume
# Copyright 2011-2012 Camptocamp SA
# #
# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
# Copyright 2013 Camptocamp SA #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU Affero General Public License as #
# published by the Free Software Foundation, either version 3 of the #
# License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU Affero General Public License for more details. #
# #
# You should have received a copy of the GNU Affero General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
{'name': "Bank statement Sale Order completion",
'version': '0.1',
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'easy',
'depends': ['account_statement_base_completion', 'sale'],
'description': """
This module improve the module account_statement_base_completion to add
support for completion rules based on Sale Orders. This was initially part of
the module account_statement_base_completion, but is now separate to keep
dependencies separate.
This module provides the following rule:
1) Match from statement line reference (based on SO number)
""",
'website': 'http://www.camptocamp.com',
'data': [
'data.xml',
],
'test': [
'test/completion_so_test.yml'],
'installable': True,
'images': [],
'auto_install': True,
'license': 'AGPL-3',
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="bank_statement_completion_rule_1" model="account.statement.completion.rule">
<field name="name">Match from line reference (based on SO number)</field>
<field name="sequence">50</field>
<field name="function_to_call">get_from_ref_and_so</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
###############################################################################
# #
# Author: Joel Grand-Guillaume #
# Copyright 2011-2012 Camptocamp SA #
# #
# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
# Copyright 2013 Camptocamp SA #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU Affero General Public License as #
# published by the Free Software Foundation, either version 3 of the #
# License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU Affero General Public License for more details. #
# #
# You should have received a copy of the GNU Affero General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
from openerp.osv import fields, orm
from tools.translate import _
from openerp.addons.account_statement_base_completion.statement import ErrorTooManyPartner
class account_statement_completion_rule(orm.Model):
_name = "account.statement.completion.rule"
_inherit = "account.statement.completion.rule"
def _get_functions(self, cr, uid, context=None):
res = super(account_statement_completion_rule, self)._get_functions(
cr, uid, context=context)
res.append(
('get_from_ref_and_so', 'From line reference (based on SO number)')
)
return res
# Should be private but data are initialised with no update XML
def get_from_ref_and_so(self, cr, uid, st_line, context=None):
"""
Match the partner based on the SO number and the reference of the
statement line. Then, call the generic get_values_for_line method to
complete other values. If more than one partner matched, raise the
ErrorTooManyPartner error.
:param int/long st_line: read of the concerned
account.bank.statement.line
:return:
A dict of value that can be passed directly to the write method of
the statement line or {}
{'partner_id': value,
'account_id': value,
...}
"""
st_obj = self.pool.get('account.bank.statement.line')
res = {}
if st_line:
so_obj = self.pool.get('sale.order')
so_id = so_obj.search(cr,
uid,
[('name', '=', st_line['ref'])],
context=context)
if so_id:
if so_id and len(so_id) == 1:
so = so_obj.browse(cr, uid, so_id[0], context=context)
res['partner_id'] = so.partner_id.id
elif so_id and len(so_id) > 1:
raise ErrorTooManyPartner(
_('Line named "%s" (Ref:%s) was matched by more '
'than one partner while looking on SO by ref.') %
(st_line['name'], st_line['ref']))
st_vals = st_obj.get_values_for_line(
cr,
uid,
profile_id=st_line['profile_id'],
master_account_id=st_line['master_account_id'],
partner_id=res.get('partner_id', False),
line_type='customer',
amount=st_line['amount'] if st_line['amount'] else 0.0,
context=context)
res.update(st_vals)
return res
_columns = {
'function_to_call': fields.selection(_get_functions, 'Method'),
}

View File

@@ -0,0 +1,44 @@
-
In order to test the banking framework for Sale Orders, I first need to
create a profile
-
!record {model: account.statement.profile, id: profile_test_so}:
name: Bank EUR Profile for SO
journal_id: account.bank_journal
commission_account_id: account.a_expense
company_id: base.main_company
balance_check: True
rule_ids:
- account_statement_base_completion.bank_statement_completion_rule_4
- account_statement_base_completion.bank_statement_completion_rule_5
- account_statement_base_completion.bank_statement_completion_rule_2
- account_statement_base_completion.bank_statement_completion_rule_3
- bank_statement_completion_rule_1
-
Now I create a statement. I create statment lines separately because I need
to find each one by XML id
-
!record {model: account.bank.statement, id: statement_test_sale1}:
name: Statement for SO
profile_id: profile_test_so
company_id: base.main_company
-
I create a statement line for a SO
-
!record {model: account.bank.statement.line, id: statement_line_so}:
name: Test autocompletion based on Sale Order Number
statement_id: statement_test_sale1
ref: SO007
date: '2013-12-20'
amount: 14981.0
-
I run the auto complete
-
!python {model: account.bank.statement}: |
result = self.button_auto_completion(cr, uid, [ref("statement_test_sale1")])
-
Now I can check that all is nice and shiny, line 1. I expect the Sale Order
Number to be recognised.
-
!assert {model: account.bank.statement.line, id: statement_line_so, string: Check completion by SO number}:
- partner_id.name == u'Luminous Technologies'

View File

@@ -48,7 +48,10 @@
"data.xml",
],
'demo_xml': [],
'test': [],
'test': [
'test/sale.yml',
'test/completion_transactionid_test.yml',
],
'installable': True,
'images': [],
'auto_install': True,

View File

@@ -0,0 +1,44 @@
-
In order to test the banking framework, I first need to create a profile
-
!record {model: account.statement.profile, id: statement_profile_transactionid}:
name: Bank EUR Profile (transaction ID)
journal_id: account.bank_journal
commission_account_id: account.a_expense
company_id: base.main_company
balance_check: True
rule_ids:
- bank_statement_completion_rule_4
- account_statement_base_completion.bank_statement_completion_rule_4
- account_statement_base_completion.bank_statement_completion_rule_5
- account_statement_base_completion.bank_statement_completion_rule_2
- account_statement_base_completion.bank_statement_completion_rule_3
-
Now I create a statement. I create statment lines separately because I need
to find each one by XML id
-
!record {model: account.bank.statement, id: statement_transactionid_test1}:
name: Statement with transaction ID
profile_id: statement_profile_transactionid
company_id: base.main_company
-
I create a statement line for a SO with transaction ID
-
!record {model: account.bank.statement.line, id: statement_line_transactionid}:
name: Test autocompletion based on SO with transaction ID
statement_id: statement_transactionid_test1
transaction_id: XXX66Z
ref: 6
date: '2014-01-06'
amount: 118.4
-
I run the auto complete
-
!python {model: account.bank.statement}: |
result = self.button_auto_completion(cr, uid, [ref("statement_profile_transactionid")])
-
Now I can check that all is nice and shiny, line 1. I expect the SO has been
recognised from the transaction ID.
-
!assert {model: account.bank.statement.line, id: statement_line_transactionid, string: Check completion by SO transaction ID}:
- partner_id.name == u'Agrolait'

View File

@@ -0,0 +1,11 @@
-
I create a new Sale Order with transaction ID
-
!record {model: sale.order, id: so_with_transaction_id}:
partner_id: base.res_partner_2
note: Invoice after delivery
payment_term: account.account_payment_term
transaction_id: XXX66Z
order_line:
- product_id: product.product_product_7
product_uom_qty: 8