mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
[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:
@@ -35,7 +35,6 @@
|
|||||||
|
|
||||||
1) Match from statement line label (based on partner field 'Bank Statement Label')
|
1) Match from statement line label (based on partner field 'Bank Statement Label')
|
||||||
2) Match from statement line label (based on partner name)
|
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)
|
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
|
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',
|
'website': 'http://www.camptocamp.com',
|
||||||
'init_xml': [],
|
'data': [
|
||||||
'update_xml': [
|
|
||||||
'statement_view.xml',
|
'statement_view.xml',
|
||||||
'partner_view.xml',
|
'partner_view.xml',
|
||||||
'data.xml',
|
'data.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo': [],
|
||||||
'test': [],
|
'test': [
|
||||||
|
'test/partner.yml',
|
||||||
|
'test/invoice.yml',
|
||||||
|
'test/supplier_invoice.yml',
|
||||||
|
'test/completion_test.yml'
|
||||||
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
|
|||||||
@@ -14,12 +14,6 @@
|
|||||||
<field name="function_to_call">get_from_label_and_partner_name</field>
|
<field name="function_to_call">get_from_label_and_partner_name</field>
|
||||||
</record>
|
</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">
|
<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="name">Match from line reference (based on Invoice number)</field>
|
||||||
<field name="sequence">40</field>
|
<field name="sequence">40</field>
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
return [
|
return [
|
||||||
('get_from_ref_and_invoice', 'From line reference (based on customer invoice number)'),
|
('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_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_field', 'From line label (based on partner field)'),
|
||||||
('get_from_label_and_partner_name', 'From line label (based on partner name)')]
|
('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)
|
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
|
# 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):
|
def get_from_label_and_partner_field(self, cr, uid, st_line, context=None):
|
||||||
"""
|
"""
|
||||||
|
|||||||
87
account_statement_base_completion/test/completion_test.yml
Normal file
87
account_statement_base_completion/test/completion_test.yml
Normal 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")
|
||||||
32
account_statement_base_completion/test/invoice.yml
Normal file
32
account_statement_base_completion/test/invoice.yml
Normal 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'
|
||||||
5
account_statement_base_completion/test/partner.yml
Normal file
5
account_statement_base_completion/test/partner.yml
Normal 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
|
||||||
31
account_statement_base_completion/test/supplier_invoice.yml
Normal file
31
account_statement_base_completion/test/supplier_invoice.yml
Normal 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'
|
||||||
@@ -49,6 +49,10 @@ class BankStatementImportParser(object):
|
|||||||
self.result_row_list = None
|
self.result_row_list = None
|
||||||
# The file buffer on which to work on
|
# The file buffer on which to work on
|
||||||
self.filebuffer = None
|
self.filebuffer = None
|
||||||
|
self.balance_start = None
|
||||||
|
self.balance_end = None
|
||||||
|
self.statement_name = None
|
||||||
|
self.statement_date = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parser_for(cls, parser_name):
|
def parser_for(cls, parser_name):
|
||||||
@@ -116,7 +120,12 @@ class BankStatementImportParser(object):
|
|||||||
create method of statement.
|
create method of statement.
|
||||||
:return: dict of vals that represent additional infos for the 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):
|
def get_st_line_vals(self, line, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
req_id = req_id[0]
|
req_id = req_id[0]
|
||||||
importer = self.browse(cr, uid, req_id, context)
|
importer = self.browse(cr, uid, req_id, context)
|
||||||
ftype = self._check_extension(importer.file_name)
|
ftype = self._check_extension(importer.file_name)
|
||||||
|
context['file_name'] = importer.file_name
|
||||||
sid = self.pool.get(
|
sid = self.pool.get(
|
||||||
'account.statement.profile').statement_import(
|
'account.statement.profile').statement_import(
|
||||||
cr,
|
cr,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class AccountStatementProfil(orm.Model):
|
|||||||
commission_analytic_id = profile.commission_analytic_id and profile.commission_analytic_id.id or False
|
commission_analytic_id = profile.commission_analytic_id and profile.commission_analytic_id.id or False
|
||||||
comm_values = {
|
comm_values = {
|
||||||
'name': 'IN ' + _('Commission line'),
|
'name': 'IN ' + _('Commission line'),
|
||||||
'date': datetime.datetime.now().date(),
|
'date': parser.get_st_vals().get('date') or datetime.datetime.now(),
|
||||||
'amount': global_commission_amount,
|
'amount': global_commission_amount,
|
||||||
'partner_id': partner_id,
|
'partner_id': partner_id,
|
||||||
'type': 'general',
|
'type': 'general',
|
||||||
@@ -65,4 +65,4 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
c.commission_account_id and c.commission_account_id.id or False
|
c.commission_account_id and c.commission_account_id.id or False
|
||||||
res['value']['commission_a'] = \
|
res['value']['commission_a'] = \
|
||||||
c.commission_analytic_id and c.commission_analytic_id.id or False
|
c.commission_analytic_id and c.commission_analytic_id.id or False
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -223,12 +223,17 @@ class AccountBankSatement(Model):
|
|||||||
move of period_id to the statement line
|
move of period_id to the statement line
|
||||||
"""
|
"""
|
||||||
for statement in self.browse(cr, uid, ids, context=context):
|
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
|
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
|
return False
|
||||||
for line in statement.line_ids:
|
for line in statement.line_ids:
|
||||||
if (line.period_id and
|
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 False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -552,12 +557,8 @@ class AccountBankSatement(Model):
|
|||||||
import_config = self.pool.get("account.statement.profile").browse(
|
import_config = self.pool.get("account.statement.profile").browse(
|
||||||
cr, uid, profile_id, context=context)
|
cr, uid, profile_id, context=context)
|
||||||
journal_id = import_config.journal_id.id
|
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,
|
return {'value': {'journal_id': journal_id,
|
||||||
'account_id': account_id,
|
'balance_check': import_config.balance_check}}
|
||||||
'balance_check': import_config.balance_check,
|
|
||||||
'credit_partner_id': credit_partner_id}}
|
|
||||||
|
|
||||||
|
|
||||||
class AccountBankSatementLine(Model):
|
class AccountBankSatementLine(Model):
|
||||||
|
|||||||
25
account_statement_so_completion/__init__.py
Normal file
25
account_statement_so_completion/__init__.py
Normal 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
|
||||||
52
account_statement_so_completion/__openerp__.py
Normal file
52
account_statement_so_completion/__openerp__.py
Normal 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',
|
||||||
|
}
|
||||||
12
account_statement_so_completion/data.xml
Normal file
12
account_statement_so_completion/data.xml
Normal 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>
|
||||||
94
account_statement_so_completion/statement.py
Normal file
94
account_statement_so_completion/statement.py
Normal 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'),
|
||||||
|
}
|
||||||
44
account_statement_so_completion/test/completion_so_test.yml
Normal file
44
account_statement_so_completion/test/completion_so_test.yml
Normal 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'
|
||||||
@@ -48,7 +48,10 @@
|
|||||||
"data.xml",
|
"data.xml",
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [],
|
'test': [
|
||||||
|
'test/sale.yml',
|
||||||
|
'test/completion_transactionid_test.yml',
|
||||||
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': True,
|
'auto_install': True,
|
||||||
|
|||||||
@@ -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'
|
||||||
11
account_statement_transactionid_completion/test/sale.yml
Normal file
11
account_statement_transactionid_completion/test/sale.yml
Normal 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
|
||||||
Reference in New Issue
Block a user