banking-addons-team team mailing list archive
-
banking-addons-team team
-
Mailing list archive
-
Message #01744
[Merge] lp:~camptocamp/banking-addons/7.0-bank-statement-reconcile-transaction_id-imp into lp:banking-addons/bank-statement-reconcile-7.0
Guewen Baconnier @ Camptocamp has proposed merging lp:~camptocamp/banking-addons/7.0-bank-statement-reconcile-transaction_id-imp into lp:banking-addons/bank-statement-reconcile-7.0.
Requested reviews:
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c): code review, no tests
Related bugs:
Bug #1270135 in Banking Addons: "[bank-statement-reconcile-7.0] Bank statement reconciliation should autocomplete with "commercial" partner entity only"
https://bugs.launchpad.net/banking-addons/+bug/1270135
For more details, see:
https://code.launchpad.net/~camptocamp/banking-addons/7.0-bank-statement-reconcile-transaction_id-imp/+merge/202806
Improvement around the Transaction IDs modules
==============================================
This proposal aims to improve the modules using transaction ids, I will start by summarizing what are they used for, then what are the existing problems and what changes I propose.
Transaction IDs?
----------------
The transaction IDs are a technical reference for a move line. They are to differentiate from the usual reference that are a reference for humans firstly (more about that here [0]). Usually, the transaction IDs are defined by external systems such as payment gateways and are a way to streamline the reconciliations between the invoices, bank statements...
Changes
-------
1) account_move_line.transaction_ref is defined in 'account_advanced_reconcile_transaction_ref' which adds a reconciliation method with transaction id.
It makes much sense to add the field in 'base_transaction_id' so we can use the field in other modules such as the bank statement completion modules. It is a pity that the field on the invoice and the sale order is 'transaction_id' and in move lines 'transaction_ref' but I prefer to keep the backward-compatibility.
So I moved these things from 'account_advanced_reconcile_transaction_ref' to 'base_transaction_id'
2) In account_advanced_reconcile_transaction_ref there is an inherit of the bank statement that copies the line's ref in the move line's transaction_id. I think this is a mismatch between the ref and the transaction_id that we have to avoid. In fact, only the transaction id of the statement lines should be copied if any, or left empty if the statement line has no transaction id.
3) A consequence of the change 2) is that the automatic reconcile from transaction ref will no longer work for those not using the transaction ids in the bank statement but only the ref. So I added a new reconciliation rule that matches 'ref' vs 'transaction id'. The only drawback is that they will need to change their configuration, but at least the rules will be clear on their intentions.
4) completion rules: 'base_transaction_id' adds a transaction_id on sales order and invoices. There is actually a completion rule that searches the bank statement information from a matching invoice with the same transaction_id. I added the same rule that searches for an invoice with the same transaction id. This is the logical continuation and a good complement when an invoice / refund was not generated by a sales order and we still need to autocomplete the bank statement.
[0] https://code.launchpad.net/~camptocamp/banking-addons/7.0-bank-statement-reconcile-account_invoice_reference/+merge/202689
--
https://code.launchpad.net/~camptocamp/banking-addons/7.0-bank-statement-reconcile-transaction_id-imp/+merge/202806
Your team Banking Addons Core Editors is subscribed to branch lp:banking-addons/bank-statement-reconcile-7.0.
=== modified file 'account_advanced_reconcile_transaction_ref/__init__.py'
--- account_advanced_reconcile_transaction_ref/__init__.py 2013-08-13 10:04:31 +0000
+++ account_advanced_reconcile_transaction_ref/__init__.py 2014-03-10 12:41:01 +0000
@@ -18,7 +18,6 @@
#
##############################################################################
-from . import account
from . import easy_reconcile
from . import base_advanced_reconciliation
from . import advanced_reconciliation
=== modified file 'account_advanced_reconcile_transaction_ref/__openerp__.py'
--- account_advanced_reconcile_transaction_ref/__openerp__.py 2014-02-21 18:18:26 +0000
+++ account_advanced_reconcile_transaction_ref/__openerp__.py 2014-03-10 12:41:01 +0000
@@ -20,8 +20,8 @@
{'name': 'Advanced Reconcile Transaction Ref',
'description': """
-Advanced reconciliation method for the module account_easy_reconcile
-=================================================
+Advanced reconciliation method for the module account_advanced_reconcile
+========================================================================
Reconcile rules with transaction_ref
""",
=== removed file 'account_advanced_reconcile_transaction_ref/account.py'
--- account_advanced_reconcile_transaction_ref/account.py 2013-12-04 16:25:04 +0000
+++ account_advanced_reconcile_transaction_ref/account.py 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# Author: Romain Deheele
-# 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.orm import Model, fields
-
-class AccountMoveLine(Model):
- """
- Inherit account.move.line class in order to add transaction_ref field
- """
- _inherit = "account.move.line"
- _columns = {
- 'transaction_ref': fields.char('Transaction Ref.', size=128),
- }
-
-class AccountBankStatement(Model):
- """
- Inherit account.bank.statement class in order to set transaction_ref info on account.move.line
- """
- _inherit = "account.bank.statement"
-
- def _prepare_move_line_vals(
- self, cr, uid, st_line, move_id, debit, credit, currency_id=False,
- amount_currency=False, account_id=False, analytic_id=False,
- partner_id=False, context=None):
-
- if context is None:
- context = {}
- res = super(AccountBankStatement, self)._prepare_move_line_vals(
- cr, uid, st_line, move_id, debit, credit,
- currency_id=currency_id,
- amount_currency=amount_currency,
- account_id=account_id,
- analytic_id=analytic_id,
- partner_id=partner_id, context=context)
- res.update({'transaction_ref': st_line.ref})
- return res
=== modified file 'account_advanced_reconcile_transaction_ref/advanced_reconciliation.py'
--- account_advanced_reconcile_transaction_ref/advanced_reconciliation.py 2013-08-13 15:10:05 +0000
+++ account_advanced_reconcile_transaction_ref/advanced_reconciliation.py 2014-03-10 12:41:01 +0000
@@ -32,7 +32,8 @@
will be skipped for reconciliation. Can be inherited to
skip on some conditions. ie: ref or partner_id is empty.
"""
- return not (move_line.get('ref') and move_line.get('partner_id'))
+ return not (move_line.get('transaction_ref') and
+ move_line.get('partner_id'))
def _matchers(self, cr, uid, rec, move_line, context=None):
return (('partner_id', move_line['partner_id']),
@@ -41,3 +42,25 @@
def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
yield ('partner_id', move_line['partner_id'])
yield ('ref', (move_line['transaction_ref'] or '').lower().strip())
+
+
+class easy_reconcile_advanced_transaction_ref_vs_ref(orm.TransientModel):
+
+ _name = 'easy.reconcile.advanced.trans_ref_vs_ref'
+ _inherit = 'easy.reconcile.advanced'
+
+ def _skip_line(self, cr, uid, rec, move_line, context=None):
+ """
+ When True is returned on some conditions, the credit move line
+ will be skipped for reconciliation. Can be inherited to
+ skip on some conditions. ie: ref or partner_id is empty.
+ """
+ return not (move_line.get('ref') and move_line.get('partner_id'))
+
+ def _matchers(self, cr, uid, rec, move_line, context=None):
+ return (('partner_id', move_line['partner_id']),
+ ('ref', move_line['ref'].lower().strip()))
+
+ def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
+ yield ('partner_id', move_line['partner_id'])
+ yield ('ref', (move_line['transaction_ref'] or '').lower().strip())
=== modified file 'account_advanced_reconcile_transaction_ref/easy_reconcile.py'
--- account_advanced_reconcile_transaction_ref/easy_reconcile.py 2013-08-13 10:04:31 +0000
+++ account_advanced_reconcile_transaction_ref/easy_reconcile.py 2014-03-10 12:41:01 +0000
@@ -32,6 +32,8 @@
methods += [
('easy.reconcile.advanced.transaction_ref',
'Advanced. Partner and Transaction Ref.'),
+ ('easy.reconcile.advanced.trans_ref_vs_ref',
+ 'Advanced. Partner and Transaction Ref. vs Ref.'),
]
return methods
=== modified file 'account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml'
--- account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml 2013-08-13 10:04:31 +0000
+++ account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml 2014-03-10 12:41:01 +0000
@@ -10,7 +10,12 @@
<group colspan="2" col="2">
<separator colspan="4" string="Advanced. Partner and Transaction Ref"/>
<label string="Match multiple debit vs multiple credit entries. Allow partial reconciliation.
-The lines should have the partner, the credit entry transaction ref. is matched vs the debit entry transaction ref. or name." colspan="4"/>
+The lines should have the partner, the credit entry transaction ref. is matched vs the debit entry transaction ref." colspan="4"/>
+ </group>
+ <group colspan="2" col="2">
+ <separator colspan="4" string="Advanced. Partner and Transaction Ref. vs Ref."/>
+ <label string="Match multiple debit vs multiple credit entries. Allow partial reconciliation.
+The lines should have the partner, the credit entry reference is matched vs the debit entry transaction reference." colspan="4"/>
</group>
</page>
</field>
=== modified file 'account_easy_reconcile/easy_reconcile.xml'
--- account_easy_reconcile/easy_reconcile.xml 2013-02-13 15:54:48 +0000
+++ account_easy_reconcile/easy_reconcile.xml 2014-03-10 12:41:01 +0000
@@ -118,7 +118,7 @@
<field name="model">account.easy.reconcile.method</field>
<field name="arch" type="xml">
<form string="Automatic Easy Reconcile Method">
- <field name="sequence"/>
+ <field name="sequence" widget="handle"/>
<field name="name"/>
<field name="write_off"/>
<field name="account_lost_id" attrs="{'required':[('write_off','>',0)]}"/>
@@ -135,7 +135,7 @@
<field name="model">account.easy.reconcile.method</field>
<field name="arch" type="xml">
<tree editable="top" string="Automatic Easy Reconcile Method">
- <field name="sequence"/>
+ <field name="sequence" widget="handle"/>
<field name="name"/>
<field name="write_off"/>
<field name="account_lost_id" attrs="{'required':[('write_off','>',0)]}"/>
=== added directory 'account_payment_transaction_id'
=== added file 'account_payment_transaction_id/__init__.py'
--- account_payment_transaction_id/__init__.py 1970-01-01 00:00:00 +0000
+++ account_payment_transaction_id/__init__.py 2014-03-10 12:41:01 +0000
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import account_payment
=== added file 'account_payment_transaction_id/__openerp__.py'
--- account_payment_transaction_id/__openerp__.py 1970-01-01 00:00:00 +0000
+++ account_payment_transaction_id/__openerp__.py 2014-03-10 12:41:01 +0000
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Copyright 2014 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': 'Account Payment - Transaction ID',
+ 'version': '1.0',
+ 'author': 'Camptocamp',
+ 'maintainer': 'Camptocamp',
+ 'license': 'AGPL-3',
+ 'category': 'Hidden',
+ 'depends': ['base_transaction_id',
+ 'account_payment',
+ 'statement_voucher_killer',
+ ],
+ 'description': """
+Compatibility module between Account Payment and Base Transaction ID.
+
+Needs `statement_voucher_killer`
+ """,
+ 'website': 'http://www.camptocamp.com',
+ 'data': [],
+ 'test': [],
+ 'installable': True,
+ 'auto_install': True,
+}
=== added file 'account_payment_transaction_id/account_payment.py'
--- account_payment_transaction_id/account_payment.py 1970-01-01 00:00:00 +0000
+++ account_payment_transaction_id/account_payment.py 2014-03-10 12:41:01 +0000
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Copyright 2014 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 orm
+
+
+class AccountPaymentPopulateStatement(orm.TransientModel):
+ _inherit = "account.payment.populate.statement"
+
+ def _prepare_statement_line_vals(self, cr, uid, payment_line, amount,
+ statement, context=None):
+ superself = super(AccountPaymentPopulateStatement, self)
+ vals = superself._prepare_statement_line_vals(
+ cr, uid, payment_line, amount, statement, context=context)
+ if payment_line.move_line_id:
+ vals['transaction_id'] = payment_line.move_line_id.transaction_ref
+ return vals
+
+
+class account_statement_from_invoice_lines(orm.TransientModel):
+ _inherit = "account.statement.from.invoice.lines"
+
+ def _prepare_statement_line_vals(self, cr, uid, move_line, s_type,
+ statement_id, amount, context=None):
+ superself = super(account_statement_from_invoice_lines, self)
+ vals = superself._prepare_statement_line_vals(
+ cr, uid, move_line, s_type, statement_id, amount, context=context)
+ vals['transaction_id'] = move_line.transaction_ref
+ return vals
=== modified file 'account_statement_transactionid_completion/__openerp__.py'
--- account_statement_transactionid_completion/__openerp__.py 2014-01-07 11:27:26 +0000
+++ account_statement_transactionid_completion/__openerp__.py 2014-03-10 12:41:01 +0000
@@ -51,6 +51,8 @@
'test': [
'test/sale.yml',
'test/completion_transactionid_test.yml',
+ 'test/invoice.yml',
+ 'test/completion_invoice_transactionid_test.yml',
],
'installable': True,
'images': [],
=== modified file 'account_statement_transactionid_completion/data.xml'
--- account_statement_transactionid_completion/data.xml 2012-06-26 09:21:35 +0000
+++ account_statement_transactionid_completion/data.xml 2014-03-10 12:41:01 +0000
@@ -3,10 +3,16 @@
<data noupdate="1">
<record id="bank_statement_completion_rule_4" model="account.statement.completion.rule">
- <field name="name">Match from line reference (based on transaction ID)</field>
+ <field name="name">Match from Sales Order using transaction ID</field>
<field name="sequence">30</field>
<field name="function_to_call">get_from_transaction_id_and_so</field>
</record>
+
+ <record id="bank_statement_completion_rule_trans_id_invoice" model="account.statement.completion.rule">
+ <field name="name">Match from Invoice using transaction ID</field>
+ <field name="sequence">40</field>
+ <field name="function_to_call">get_from_transaction_id_and_invoice</field>
+ </record>
</data>
</openerp>
=== modified file 'account_statement_transactionid_completion/statement.py'
--- account_statement_transactionid_completion/statement.py 2013-09-11 09:12:14 +0000
+++ account_statement_transactionid_completion/statement.py 2014-03-10 12:41:01 +0000
@@ -33,8 +33,12 @@
def _get_functions(self, cr, uid, context=None):
res = super(AccountStatementCompletionRule, self)._get_functions(
cr, uid, context=context)
- res.append(('get_from_transaction_id_and_so',
- 'From line reference (based on SO transaction ID)'))
+ res += [
+ ('get_from_transaction_id_and_so',
+ 'Match Sales Order using transaction ID'),
+ ('get_from_transaction_id_and_invoice',
+ 'Match Invoice using transaction ID'),
+ ]
return res
_columns = {
@@ -79,6 +83,52 @@
res.update(st_vals)
return res
+ def get_from_transaction_id_and_invoice(self, cr, uid, st_line, context=None):
+ """
+ Match the partner based on the transaction ID field of the invoice.
+ Then, call the generic st_line method to complete other values.
+
+ In that case, we always fullfill the reference of the line with the invoice name.
+
+ :param dict 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 = {}
+ invoice_obj = self.pool.get('account.invoice')
+ invoice_id = invoice_obj.search(
+ cr, uid,
+ [('transaction_id', '=', st_line['transaction_id'])],
+ context=context)
+ if len(invoice_id) > 1:
+ raise ErrorTooManyPartner(
+ _('Line named "%s" (Ref:%s) was matched by more than '
+ 'one partner.') % (st_line['name'], st_line['ref']))
+ elif len(invoice_id) == 1:
+ invoice = invoice_obj.browse(cr, uid, invoice_id[0],
+ context=context)
+ res['partner_id'] = invoice.partner_id.id
+ # we want the move to have the same ref than the found
+ # invoice's move, thus it will be easier to link them for the
+ # accountants
+ if invoice.move_id:
+ res['ref'] = invoice.move_id.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=st_line['type'],
+ amount=st_line['amount'] if st_line['amount'] else 0.0,
+ context=context)
+ res.update(st_vals)
+ return res
+
class AccountStatementLine(Model):
_inherit = "account.bank.statement.line"
@@ -92,3 +142,38 @@
serialization_field='additionnal_bank_fields',
help="Transaction id from the financial institute"),
}
+
+
+class AccountBankStatement(Model):
+ _inherit = "account.bank.statement"
+
+ def _prepare_move_line_vals(
+ self, cr, uid, st_line, move_id, debit, credit, currency_id=False,
+ amount_currency=False, account_id=False, analytic_id=False,
+ partner_id=False, context=None):
+ """Add the period_id from the statement line date to the move preparation.
+ Originaly, it was taken from the statement period_id
+
+ :param browse_record st_line: account.bank.statement.line record to
+ create the move from.
+ :param int/long move_id: ID of the account.move to link the move line
+ :param float debit: debit amount of the move line
+ :param float credit: credit amount of the move line
+ :param int/long currency_id: ID of currency of the move line to create
+ :param float amount_currency: amount of the debit/credit expressed in the currency_id
+ :param int/long account_id: ID of the account to use in the move line if different
+ from the statement line account ID
+ :param int/long analytic_id: ID of analytic account to put on the move line
+ :param int/long partner_id: ID of the partner to put on the move line
+ :return: dict of value to create() the account.move.line
+ """
+ res = super(AccountBankStatement, self)._prepare_move_line_vals(
+ cr, uid, st_line, move_id, debit, credit,
+ currency_id=currency_id,
+ amount_currency=amount_currency,
+ account_id=account_id,
+ analytic_id=analytic_id,
+ partner_id=partner_id, context=context)
+ if st_line.transaction_id:
+ res['transaction_ref'] = st_line.transaction_id
+ return res
=== modified file 'account_statement_transactionid_completion/statement_view.xml'
--- account_statement_transactionid_completion/statement_view.xml 2012-12-18 21:06:21 +0000
+++ account_statement_transactionid_completion/statement_view.xml 2014-03-10 12:41:01 +0000
@@ -7,13 +7,13 @@
<field name="model">account.bank.statement</field>
<field name="inherit_id" ref="account.view_bank_statement_form" />
<field eval="20" name="priority"/>
- <field name="type">form</field>
<field name="arch" type="xml">
- <data>
- <xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='label']" position="after">
- <field name="transaction_id" />
- </xpath>
- </data>
+ <xpath expr="//field[@name='line_ids']/form//field[@name='label']" position="after">
+ <field name="transaction_id" />
+ </xpath>
+ <xpath expr="//field[@name='line_ids']/tree/field[@name='ref']" position="after">
+ <field name="transaction_id" />
+ </xpath>
</field>
</record>
=== added file 'account_statement_transactionid_completion/test/completion_invoice_transactionid_test.yml'
--- account_statement_transactionid_completion/test/completion_invoice_transactionid_test.yml 1970-01-01 00:00:00 +0000
+++ account_statement_transactionid_completion/test/completion_invoice_transactionid_test.yml 2014-03-10 12:41:01 +0000
@@ -0,0 +1,49 @@
+-
+ In order to test the banking framework, I first need to create a profile
+-
+ !record {model: account.statement.profile, id: statement_profile_invoice_transactionid}:
+ name: Bank EUR Profile (invoice 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_trans_id_invoice
+-
+ 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_invoice_transactionid_test1}:
+ name: Statement with transaction ID
+ profile_id: statement_profile_invoice_transactionid
+ company_id: base.main_company
+-
+ I create a statement line for an invoice with transaction ID
+-
+ !record {model: account.bank.statement.line, id: statement_line_invoice_transactionid}:
+ name: Test autocompletion based on invoice with transaction ID
+ statement_id: statement_invoice_transactionid_test1
+ transaction_id: XXX77Z
+ ref: 6
+ date: !eval time.strftime('%Y-%m-%d')
+ amount: 450
+-
+ I run the auto complete
+-
+ !python {model: account.bank.statement}: |
+ result = self.button_auto_completion(cr, uid, [ref("statement_invoice_transactionid_test1")])
+-
+ Now I can check that all is nice and shiny, line 1. I expect the invoice has been
+ recognised from the transaction ID.
+-
+ !assert {model: account.bank.statement.line, id: statement_line_invoice_transactionid, string: Check completion by Invoice transaction ID}:
+ - partner_id.name == u'Agrolait'
+-
+ I verify if the reference of the move has been copied to the statement line
+-
+ !python {model: account.bank.statement.line}: |
+ statement_line = self.browse(cr, uid, ref('statement_line_invoice_transactionid'))
+ invoice_obj = self.pool['account.invoice']
+ invoice = invoice_obj.browse(cr, uid, ref('invoice_with_transaction_id'))
+ reference = invoice.move_id.ref
+ assert statement_line.ref == reference
=== modified file 'account_statement_transactionid_completion/test/completion_transactionid_test.yml'
--- account_statement_transactionid_completion/test/completion_transactionid_test.yml 2014-01-07 11:27:26 +0000
+++ account_statement_transactionid_completion/test/completion_transactionid_test.yml 2014-03-10 12:41:01 +0000
@@ -35,7 +35,7 @@
I run the auto complete
-
!python {model: account.bank.statement}: |
- result = self.button_auto_completion(cr, uid, [ref("statement_profile_transactionid")])
+ result = self.button_auto_completion(cr, uid, [ref("statement_transactionid_test1")])
-
Now I can check that all is nice and shiny, line 1. I expect the SO has been
recognised from the transaction ID.
=== added file 'account_statement_transactionid_completion/test/invoice.yml'
--- account_statement_transactionid_completion/test/invoice.yml 1970-01-01 00:00:00 +0000
+++ account_statement_transactionid_completion/test/invoice.yml 2014-03-10 12:41:01 +0000
@@ -0,0 +1,30 @@
+-
+ I create a new invoice with transaction ID
+-
+ !record {model: account.invoice, id: invoice_with_transaction_id}:
+ account_id: account.a_recv
+ company_id: base.main_company
+ currency_id: base.EUR
+ partner_id: base.res_partner_2
+ transaction_id: XXX77Z
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PCSC234] PC Assemble SC234'
+ price_unit: 450.0
+ quantity: 1.0
+ product_id: product.product_product_3
+ uos_id: product.product_uom_unit
+ journal_id: account.bank_journal
+ reference_type: none
+-
+ I called the "Confirm Draft Invoices" wizard
+-
+ !record {model: account.invoice.confirm, id: invoice_transaction_id_confirm}:
+ {}
+-
+ I clicked on Confirm Invoices Button
+-
+ !python {model: account.invoice.confirm}: |
+ self.invoice_confirm(cr, uid, [ref("invoice_transaction_id_confirm")], {"lang": 'en_US',
+ "tz": False, "active_model": "account.invoice", "active_ids": [ref("invoice_with_transaction_id")],
+ "type": "out_invoice", "active_id": ref("invoice_with_transaction_id"), })
=== modified file 'base_transaction_id/__init__.py'
--- base_transaction_id/__init__.py 2012-05-16 14:09:21 +0000
+++ base_transaction_id/__init__.py 2014-03-10 12:41:01 +0000
@@ -22,3 +22,4 @@
from . import invoice
from . import sale
from . import stock
+from . import account_move
=== added file 'base_transaction_id/account_move.py'
--- base_transaction_id/account_move.py 1970-01-01 00:00:00 +0000
+++ base_transaction_id/account_move.py 2014-03-10 12:41:01 +0000
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Copyright 2014 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 orm, fields
+
+
+class account_move_line(orm.Model):
+ _inherit = 'account.move.line'
+
+ _columns = {
+ 'transaction_ref': fields.char('Transaction Ref.',
+ select=True),
+ }
+
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ if default is None:
+ default = {}
+ default['transaction_ref'] = False
+ return super(account_move_line, self).\
+ copy_data(cr, uid, id, default=default, context=context)
=== modified file 'base_transaction_id/invoice.py'
--- base_transaction_id/invoice.py 2012-12-20 13:37:01 +0000
+++ base_transaction_id/invoice.py 2014-03-10 12:41:01 +0000
@@ -29,8 +29,22 @@
_columns = {
'transaction_id': fields.char(
'Transaction id',
- size=128,
- required=False,
select=1,
- help="Transction id from the financial institute"),
+ help="Transaction id from the financial institute"),
}
+
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ if default is None:
+ default = {}
+ default['transaction_id'] = False
+ return super(AccountInvoice, self).\
+ copy_data(cr, uid, id, default=default, context=context)
+
+ def finalize_invoice_move_lines(self, cr, uid, invoice_browse, move_lines):
+ if invoice_browse.transaction_id:
+ invoice_account_id = invoice_browse.account_id.id
+ for line in move_lines:
+ # tuple (0, 0, {values})
+ if invoice_account_id == line[2]['account_id']:
+ line[2]['transaction_ref'] = invoice_browse.transaction_id
+ return move_lines
=== modified file 'statement_voucher_killer/voucher.py'
--- statement_voucher_killer/voucher.py 2013-08-27 06:20:04 +0000
+++ statement_voucher_killer/voucher.py 2014-03-10 12:41:01 +0000
@@ -72,18 +72,23 @@
s_type = 'customer'
elif line.journal_id.type in ('purchase', 'purhcase_refund'):
s_type = 'supplier'
- statement_line_obj.create(cr, uid, {
- 'name': line.name or '?',
+ vals = self._prepare_statement_line_vals(
+ cr, uid, line, s_type, statement_id, amount, context=context)
+ statement_line_obj.create(cr, uid, vals, context=context)
+ return {'type': 'ir.actions.act_window_close'}
+
+ def _prepare_statement_line_vals(self, cr, uid, move_line, s_type,
+ statement_id, amount, context=None):
+ return {'name': move_line.name or '?',
'amount': amount,
'type': s_type,
- 'partner_id': line.partner_id.id,
- 'account_id': line.account_id.id,
+ 'partner_id': move_line.partner_id.id,
+ 'account_id': move_line.account_id.id,
'statement_id': statement_id,
- 'ref': line.ref,
+ 'ref': move_line.ref,
'voucher_id': False,
'date': time.strftime('%Y-%m-%d'),
- }, context=context)
- return {'type': 'ir.actions.act_window_close'}
+ }
class AccountPaymentPopulateStatement(orm.TransientModel):
@@ -114,16 +119,23 @@
if not line.move_line_id.id:
continue
context.update({'move_line_ids': [line.move_line_id.id]})
- st_line_id = statement_line_obj.create(cr, uid, {
- 'name': line.order_id.reference or '?',
- 'amount': - amount,
+ vals = self._prepare_statement_line_vals(
+ cr, uid, line, -amount, statement, context=context)
+ st_line_id = statement_line_obj.create(cr, uid, vals,
+ context=context)
+
+ line_obj.write(cr, uid, [line.id], {'bank_statement_line_id': st_line_id})
+ return {'type': 'ir.actions.act_window_close'}
+
+ def _prepare_statement_line_vals(self, cr, uid, payment_line, amount,
+ statement, context=None):
+ return {'name': payment_line.order_id.reference or '?',
+ 'amount': amount,
'type': 'supplier',
- 'partner_id': line.partner_id.id,
- 'account_id': line.move_line_id.account_id.id,
+ 'partner_id': payment_line.partner_id.id,
+ 'account_id': payment_line.move_line_id.account_id.id,
'statement_id': statement.id,
- 'ref': line.communication,
- 'date': line.date or line.ml_maturity_date or statement.date,
- }, context=context)
-
- line_obj.write(cr, uid, [line.id], {'bank_statement_line_id': st_line_id})
- return {'type': 'ir.actions.act_window_close'}
+ 'ref': payment_line.communication,
+ 'date': (payment_line.date or payment_line.ml_maturity_date or
+ statement.date)
+ }