banking-addons-team team mailing list archive
-
banking-addons-team team
-
Mailing list archive
-
Message #00600
[Merge] lp:~therp-nl/banking-addons/6.1-match_multiple_invoices_split into lp:banking-addons
Stefan Rijnhart (Therp) has proposed merging lp:~therp-nl/banking-addons/6.1-match_multiple_invoices_split into lp:banking-addons.
Requested reviews:
Banking Addons Team (banking-addons-team)
For more details, see:
https://code.launchpad.net/~therp-nl/banking-addons/6.1-match_multiple_invoices_split/+merge/159348
=== Don't merge yet, work in progress ===
--
https://code.launchpad.net/~therp-nl/banking-addons/6.1-match_multiple_invoices_split/+merge/159348
Your team Banking Addons Team is requested to review the proposed merge of lp:~therp-nl/banking-addons/6.1-match_multiple_invoices_split into lp:banking-addons.
=== modified file 'account_banking/__openerp__.py'
--- account_banking/__openerp__.py 2012-05-07 11:49:08 +0000
+++ account_banking/__openerp__.py 2013-05-24 06:42:24 +0000
@@ -47,6 +47,9 @@
'wizard/banking_transaction_wizard.xml',
'workflow/account_invoice.xml',
],
+ 'js': [
+ 'static/src/js/account_banking.js',
+ ],
'demo_xml': [],
'external_dependencies': {
'python' : ['BeautifulSoup'],
=== modified file 'account_banking/account_banking_view.xml'
--- account_banking/account_banking_view.xml 2013-04-25 08:15:21 +0000
+++ account_banking/account_banking_view.xml 2013-05-24 06:42:24 +0000
@@ -292,9 +292,12 @@
<xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
<field name="match_type"/>
<field name="residual"/>
- <button name="match_wizard" states="draft"
+ <field name="parent_id" invisible="1" />
+ <button name="match_wizard"
string="Match"
icon="terp-gtk-jump-to-ltr"
+ attrs="{'invisible': ['|', ('parent_id', '!=', False),
+ ('state', '!=', 'draft')]}"
type="object"/>
<field name="match_multi" invisible="1"/>
<field name="duplicate" invisible="1"/>
@@ -523,9 +526,12 @@
<field name="amount"/>
<field name="match_type"/>
<field name="residual"/>
- <button name="match_wizard" states="draft"
+ <field name="parent_id" invisible="1" />
+ <button name="match_wizard"
string="Match"
icon="terp-gtk-jump-to-ltr"
+ attrs="{'invisible': ['|', ('parent_id', '!=', False),
+ ('state', '!=', 'draft')]}"
type="object"/>
<field name="match_multi" invisible="1"/>
<field name="duplicate" invisible="1"/>
=== modified file 'account_banking/banking_import_transaction.py'
--- account_banking/banking_import_transaction.py 2013-05-20 08:07:48 +0000
+++ account_banking/banking_import_transaction.py 2013-05-24 06:42:24 +0000
@@ -1572,6 +1572,22 @@
return res
+ def unlink(self, cr, uid, ids, context=None):
+ """
+ Unsplit if this if a split transaction
+ """
+ for this in self.browse(cr, uid, ids, context):
+ if this.parent_id:
+ this.parent_id.write(
+ {'transferred_amount':
+ this.parent_id.transferred_amount + \
+ this.transferred_amount,
+ })
+ this.parent_id.refresh()
+ return super(banking_import_transaction, self).unlink(
+ cr, uid, ids, context=context)
+
+
column_map = {
# used in bank_import.py, converting non-osv transactions
'statement_id': 'statement',
@@ -1623,7 +1639,7 @@
'duplicate': fields.boolean('duplicate'),
'statement_line_id': fields.many2one(
'account.bank.statement.line', 'Statement line',
- ondelete='CASCADE'),
+ ondelete='cascade'),
'statement_id': fields.many2one(
'account.bank.statement', 'Statement'),
'parent_id': fields.many2one(
@@ -1694,7 +1710,7 @@
_columns = {
'import_transaction_id': fields.many2one(
'banking.import.transaction',
- 'Import transaction', readonly=True, delete='cascade'),
+ 'Import transaction', readonly=True, ondelete='cascade'),
'match_multi': fields.related(
'import_transaction_id', 'match_multi', type='boolean',
string='Multi match', readonly=True),
@@ -1715,6 +1731,8 @@
'state': fields.selection(
[('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State',
readonly=True, required=True),
+ 'parent_id': fields.many2one('account.bank.statement.line',
+ 'Parent'),
}
_defaults = {
@@ -1857,6 +1875,8 @@
def unlink(self, cr, uid, ids, context=None):
"""
Don't allow deletion of a confirmed statement line
+ If this statement line comes from a split transaction, give the
+ amount back
"""
if type(ids) is int:
ids = [ids]
@@ -1866,6 +1886,12 @@
_('Confirmed Statement Line'),
_("You cannot delete a confirmed Statement Line"
": '%s'" % line.name))
+ if line.parent_id:
+ line.parent_id.write(
+ {
+ 'amount': line.parent_id.amount + line.amount,
+ })
+ line.parent_id.refresh()
return super(account_bank_statement_line, self).unlink(
cr, uid, ids, context=context)
@@ -1905,6 +1931,50 @@
'import_transaction_id': res},
context=context)
+ def split_off(self, cr, uid, ids, amount, context=None):
+ """
+ Create a child statement line with amount, deduce that from this line,
+ change transactions accordingly
+ """
+ if context is None:
+ context = {}
+
+ transaction_pool = self.pool.get('banking.import.transaction')
+
+ child_statement_ids = []
+ for this in self.browse(cr, uid, ids, context):
+ transaction_data = transaction_pool.copy_data(
+ cr, uid, this.import_transaction_id.id)
+ transaction_data['transferred_amount'] = amount
+ transaction_data['message'] = (
+ (transaction_data['message'] or '') + _(' (split)'))
+ transaction_data['parent_id'] = this.import_transaction_id.id
+ transaction_id = transaction_pool.create(
+ cr,
+ uid,
+ transaction_data,
+ context=dict(
+ context, transaction_no_duplicate_search=True))
+
+ statement_line_data = self.copy_data(
+ cr, uid, this.id)
+ statement_line_data['amount'] = amount
+ statement_line_data['name'] = (
+ (statement_line_data['name'] or '') + _(' (split)'))
+ statement_line_data['import_transaction_id'] = transaction_id
+ statement_line_data['parent_id'] = this.id
+ statement_line_id = self.create(
+ cr, uid, statement_line_data, context=context)
+
+ child_statement_ids.append(statement_line_id)
+ transaction_pool.write(
+ cr, uid, transaction_id, {
+ 'statement_line_id': statement_line_id,
+ }, context=context)
+ this.write({'amount': this.amount - amount})
+
+ return child_statement_ids
+
account_bank_statement_line()
class account_bank_statement(osv.osv):
=== modified file 'account_banking/i18n/nl.po'
--- account_banking/i18n/nl.po 2012-05-02 15:09:49 +0000
+++ account_banking/i18n/nl.po 2013-05-24 06:42:24 +0000
@@ -139,9 +139,9 @@
msgstr "remote_bank_bic"
#. module: account_banking
-#: field:banking.transaction.wizard,manual_invoice_id:0
-msgid "Match this invoice"
-msgstr "Match deze factuur"
+#: field:banking.transaction.wizard,manual_invoice_ids:0
+msgid "Match one or more invoices"
+msgstr "Match een of meerdere facturen"
#. module: account_banking
#: field:banking.import.transaction,remote_bank_ibei:0
@@ -1022,9 +1022,9 @@
msgstr "Herzien"
#. module: account_banking
-#: field:banking.transaction.wizard,manual_move_line_id:0
-msgid "Or match this entry"
-msgstr "Of koppel deze boekingsregel"
+#: field:banking.transaction.wizard,manual_move_line_ids:0
+msgid "Or match one or more entries"
+msgstr "Of koppel deze boekingsregel(s)"
#. module: account_banking
#: help:payment.mode.type,name:0
=== added directory 'account_banking/static'
=== added directory 'account_banking/static/src'
=== added directory 'account_banking/static/src/js'
=== added file 'account_banking/static/src/js/account_banking.js'
--- account_banking/static/src/js/account_banking.js 1970-01-01 00:00:00 +0000
+++ account_banking/static/src/js/account_banking.js 2013-05-24 06:42:24 +0000
@@ -0,0 +1,51 @@
+/*############################################################################
+#
+# Copyright (C) 2013 Therp BV (<http://therp.nl>).
+#
+# All other contributions are (C) by their respective contributors
+#
+# All Rights Reserved
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract EduSense BV
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################*/
+
+openerp.account_banking = function(openerp)
+{
+ var _t = openerp.web._t;
+ openerp.web.Dialog.include(
+ {
+ on_close: function()
+ {
+ this._super.apply(this, arguments);
+ if(this.dialog_title == _t("Match transaction"))
+ {
+ if(this.widget_parent.widget_children[0].views.form.controller)
+ {
+ this.widget_parent.widget_children[0].views.form.controller.reload();
+ }
+ if(this.widget_parent.widget_children[0].views.page.controller)
+ {
+ this.widget_parent.widget_children[0].views.page.controller.reload();
+ }
+ }
+ },
+ });
+}
=== modified file 'account_banking/wizard/banking_transaction_wizard.py'
--- account_banking/wizard/banking_transaction_wizard.py 2012-12-01 18:31:34 +0000
+++ account_banking/wizard/banking_transaction_wizard.py 2013-05-24 06:42:24 +0000
@@ -94,8 +94,8 @@
# The following fields get never written
# they are just triggers for manual matching
# which populates regular fields on the transaction
- manual_invoice_id = vals.pop('manual_invoice_id', False)
- manual_move_line_id = vals.pop('manual_move_line_id', False)
+ manual_invoice_ids = vals.pop('manual_invoice_ids', [])
+ manual_move_line_ids = vals.pop('manual_move_line_ids', [])
# Support for writing fields.related is still flakey:
# https://bugs.launchpad.net/openobject-server/+bug/915975
@@ -167,55 +167,93 @@
_("No entry found for the selected invoice. " +
"Try manual reconciliation."))
- if manual_move_line_id or manual_invoice_id:
+ if manual_move_line_ids or manual_invoice_ids:
move_line_obj = self.pool.get('account.move.line')
invoice_obj = self.pool.get('account.invoice')
statement_line_obj = self.pool.get('account.bank.statement.line')
- for wiz in self.browse(
- cr, uid, ids, context=context):
- move_line_id = False
- invoice_id = manual_invoice_id
- if invoice_id:
- invoice = invoice_obj.browse(
- cr, uid, manual_invoice_id, context=context)
+ manual_invoice_ids = (
+ [i[1] for i in manual_invoice_ids if i[0]==4] +
+ [j for i in manual_invoice_ids if i[0]==6 for j in i[2]])
+ manual_move_line_ids = (
+ [i[1] for i in manual_move_line_ids if i[0]==4] +
+ [j for i in manual_move_line_ids if i[0]==6 for j in i[2]])
+ for wiz in self.browse(cr, uid, ids, context=context):
+ #write can be called multiple times for the same values
+ #that doesn't hurt above, but it does here
+ if wiz.match_type and (
+ len(manual_move_line_ids) > 1 or
+ len(manual_invoice_ids) > 1):
+ continue
+
+ todo = []
+
+ for invoice in invoice_obj.browse(
+ cr, uid, manual_invoice_ids, context=context):
+ found_move_line = False
if invoice.move_id:
for line in invoice.move_id.line_id:
if line.account_id.type in ('receivable', 'payable'):
- move_line_id = line.id
+ todo.append((invoice.id, line.id))
+ found_move_line = True
break
- if not move_line_id:
- osv.except_osv(
+ if not found_move_line:
+ raise osv.except_osv(
_("Cannot select for reconcilion"),
_("No entry found for the selected invoice. "))
- else:
- move_line_id = manual_move_line_id
- move_line = move_line_obj.read(
- cr, uid, move_line_id, ['invoice'], context=context)
- invoice_id = (move_line['invoice'] and
- move_line['invoice'][0])
- vals = {
- 'move_line_id': move_line_id,
- 'move_line_ids': [(6, 0, [move_line_id])],
- 'invoice_id': invoice_id,
- 'invoice_ids': [(6, 0, invoice_id and
- [invoice_id] or [])],
- 'match_type': 'manual',
- }
- transaction_obj.clear_and_write(
- cr, uid, wiz.import_transaction_id.id,
- vals, context=context)
- st_line_vals = {
- 'account_id': move_line_obj.read(
- cr, uid, move_line_id,
- ['account_id'], context=context)['account_id'][0],
- }
- if invoice_id:
- st_line_vals['partner_id'] = invoice_obj.read(
- cr, uid, invoice_id,
- ['partner_id'], context=context)['partner_id'][0]
- statement_line_obj.write(
- cr, uid, wiz.import_transaction_id.statement_line_id.id,
- st_line_vals, context=context)
+ for move_line_id in manual_move_line_ids:
+ todo_entry = [False, move_line_id]
+ move_line=move_line_obj.read(
+ cr,
+ uid,
+ move_line_id,
+ ['invoice'],
+ context=context)
+ if move_line['invoice']:
+ todo_entry[0] = move_line['invoice'][0]
+ todo.append(todo_entry)
+
+ while todo:
+ todo_entry = todo.pop()
+ move_line = move_line_obj.browse(
+ cr, uid, todo_entry[1], context)
+ transaction_id = wiz.import_transaction_id.id
+ statement_line_id = wiz.statement_line_id.id
+
+ if len(todo) > 0:
+ statement_line_id = wiz.statement_line_id.split_off(
+ move_line.credit or move_line.debit)[0]
+ transaction_id = statement_line_obj.browse(
+ cr,
+ uid,
+ statement_line_id,
+ context=context).import_transaction_id.id
+
+ vals = {
+ 'move_line_id': todo_entry[1],
+ 'move_line_ids': [(6, 0, [todo_entry[1]])],
+ 'invoice_id': todo_entry[0],
+ 'invoice_ids': [(6, 0,
+ [todo_entry[0]] if todo_entry[0] else [])],
+ 'match_type': 'manual',
+ }
+
+ transaction_obj.clear_and_write(
+ cr, uid, transaction_id, vals, context=context)
+
+ st_line_vals = {
+ 'account_id': move_line_obj.read(
+ cr, uid, todo_entry[1],
+ ['account_id'], context=context)['account_id'][0],
+ }
+
+ if todo_entry[0]:
+ st_line_vals['partner_id'] = invoice_obj.read(
+ cr, uid, todo_entry[0],
+ ['partner_id'], context=context)['partner_id'][0]
+
+ statement_line_obj.write(
+ cr, uid, statement_line_id,
+ st_line_vals, context=context)
return res
def trigger_write(self, cr, uid, ids, context=None):
@@ -247,14 +285,21 @@
account_id = setting.default_debit_account_id and setting.default_debit_account_id.id
statement_pool.write(cr, uid, wiz.statement_line_id.id, {'account_id':account_id})
- self.write(cr, uid, wiz.id, {'partner_id': False}, context=context)
-
- wizs = self.read(
- cr, uid, ids, ['import_transaction_id'], context=context)
- trans_ids = [x['import_transaction_id'][0] for x in wizs
- if x['import_transaction_id']]
- self.pool.get('banking.import.transaction').clear_and_write(
- cr, uid, trans_ids, context=context)
+ wiz.write({'partner_id': False})
+
+ if wiz.statement_line_id:
+ #delete splits causing an unsplit if this is a split
+ #transaction
+ statement_pool.unlink(cr, uid,
+ statement_pool.search(cr, uid,
+ [('parent_id', '=', wiz.statement_line_id.id)],
+ context=context),
+ context=context)
+
+ if wiz.import_transaction_id:
+ wiz.import_transaction_id.clear_and_write()
+
+
return True
def reverse_duplicate(self, cr, uid, ids, context=None):
@@ -281,7 +326,7 @@
return res
def button_done(self, cr, uid, ids, context=None):
- return {'nodestroy': False, 'type': 'ir.actions.act_window_close'}
+ return {'type': 'ir.actions.act_window_close'}
_defaults = {
# 'match_type': _get_default_match_type,
@@ -305,6 +350,9 @@
'statement_line_id', 'partner_id',
type='many2one', relation='res.partner',
string="Partner", readonly=True),
+ 'statement_line_parent_id': fields.related(
+ 'statement_line_id', 'parent_id', type='many2one',
+ relation='account.bank.statement.line', readonly=True),
'import_transaction_id': fields.related(
'statement_line_id', 'import_transaction_id',
string="Import transaction",
@@ -350,14 +398,17 @@
'match_type': fields.related(
'import_transaction_id', 'match_type',
type="char", size=16, string='Match type', readonly=True),
- 'manual_invoice_id': fields.many2one(
- 'account.invoice', 'Match this invoice',
+ 'manual_invoice_ids': fields.many2many(
+ 'account.invoice',
+ 'banking_transaction_wizard_account_invoice_rel',
+ 'wizard_id', 'invoice_id', string='Match one or more invoices',
domain=[('reconciled', '=', False)]),
- 'manual_move_line_id': fields.many2one(
- 'account.move.line', 'Or match this entry',
+ 'manual_move_line_ids': fields.many2many(
+ 'account.move.line',
+ 'banking_transaction_wizard_account_move_line_rel',
+ 'wizard_id', 'move_line_id', string='Or match one or more entries',
domain=[('account_id.reconcile', '=', True),
- ('reconcile_id', '=', False)],
- ),
+ ('reconcile_id', '=', False)]),
'payment_option': fields.related('import_transaction_id','payment_option', string='Payment Difference', type='selection', required=True,
selection=[('without_writeoff', 'Keep Open'),('with_writeoff', 'Reconcile Payment Balance')]),
'writeoff_analytic_id': fields.related(
=== modified file 'account_banking/wizard/banking_transaction_wizard.xml'
--- account_banking/wizard/banking_transaction_wizard.xml 2013-01-13 14:11:44 +0000
+++ account_banking/wizard/banking_transaction_wizard.xml 2013-05-24 06:42:24 +0000
@@ -9,6 +9,7 @@
<form string="Match transaction">
<!-- fields used for form logic -->
<field name="payment_order_ids" invisible="True"/>
+ <field name="statement_line_parent_id" invisible="True"/>
<field name="invoice_ids" invisible="True"/>
<field name="move_line_ids" invisible="True"/>
<field name="match_multi" invisible="True"/>
@@ -89,30 +90,18 @@
name="trigger_match"
type="object"
string="Match again"/>
- <!-- Manual selection -->
</page>
+ <!-- Manual selection -->
<page string="Manual match">
- <field name="manual_invoice_id"/>
- <!--
- Specify alternative tree_view_ref as a
- workaround for lp:1073521 in OpenERP 6.1
- Need to also define 'view_mode' to prevent
- an instant editable tree view
- reconstruction by account.move.line's
- fields_view_get().
- Both are not needed in OpenERP 6.0 or 7.0.
- -->
- <field name="manual_move_line_id"
- context="{
- 'tree_view_ref': 'account.view_move_line_tax_tree',
- 'view_mode': 'yes'
- }"
- />
- <newline/>
- <button colspan="1"
- name="trigger_write"
+ <field name="manual_invoice_ids" colspan="4"
+ context="{'search_default_partner_id': partner_id}"
+ />
+ <field name="manual_move_line_ids" colspan="4"
+ context="{'search_default_partner_id': partner_id}"
+ />
+ <button name="trigger_write"
type="object"
- string="Match"/>
+ string="Match" />
</page>
<page string="Write-Off" attrs="{'invisible': [('match_type', '=', False)]}">
<group colspan="2" col="2">
@@ -139,7 +128,7 @@
</notebook>
<group colspan="2">
<separator/>
- <button icon="gtk-ok" string="Done" special="cancel"/>
+ <button icon="gtk-ok" string="Close" special="cancel"/>
</group>
</group>
</form>
Follow ups