diff --git a/account_banking/__openerp__.py b/account_banking/__openerp__.py
index 81bc377d5..bce225cd4 100644
--- a/account_banking/__openerp__.py
+++ b/account_banking/__openerp__.py
@@ -41,8 +41,12 @@
'wizard/bank_import_view.xml',
'account_banking_view.xml',
'wizard/banking_transaction_wizard.xml',
+ 'wizard/link_partner.xml',
'workflow/account_invoice.xml',
],
+ 'js': [
+ 'static/src/js/account_banking.js',
+ ],
'external_dependencies': {
'python' : ['BeautifulSoup'],
},
diff --git a/account_banking/account_banking_view.xml b/account_banking/account_banking_view.xml
index c9fce3dea..6200cdfee 100644
--- a/account_banking/account_banking_view.xml
+++ b/account_banking/account_banking_view.xml
@@ -230,6 +230,13 @@
-->
+
+
@@ -242,10 +249,14 @@
position="after">
-
+
+ attrs="{'invisible': ['|', ('parent_id', '!=', False),
+ ('state', '!=', 'draft')]}"
+ type="object"
+ />
@@ -310,6 +321,13 @@
+
+
@@ -319,10 +337,14 @@
+
+ attrs="{'invisible': ['|', ('parent_id', '!=', False),
+ ('state', '!=', 'draft')]}"
+ type="object"
+ />
diff --git a/account_banking/banking_import_transaction.py b/account_banking/banking_import_transaction.py
index 5dadb1747..082fa4e24 100644
--- a/account_banking/banking_import_transaction.py
+++ b/account_banking/banking_import_transaction.py
@@ -181,7 +181,7 @@ class banking_import_transaction(orm.Model):
Match on ID of invoice (reference, name or number, whatever
available and sensible)
'''
- if invoice.reference:
+ if invoice.reference and len(invoice.reference) > 2:
# Reference always comes first, as it is manually set for a
# reason.
iref = invoice.reference.upper()
@@ -189,7 +189,7 @@ class banking_import_transaction(orm.Model):
return True
if invoice.type.startswith('in_'):
# Internal numbering, no likely match on number
- if invoice.name:
+ if invoice.name and len(invoice.name) > 2:
iname = invoice.name.upper()
if iname in ref or iname in msg:
return True
@@ -334,7 +334,7 @@ class banking_import_transaction(orm.Model):
move_line = False
partial = False
- elif len(candidates) == 1:
+ elif len(candidates) == 1 and candidates[0].invoice:
# Mismatch in amounts
move_line = candidates[0]
invoice = move_line.invoice
@@ -382,10 +382,10 @@ class banking_import_transaction(orm.Model):
if x.partner_id.id == move_line.partner_id.id
]
- return (trans, self._get_move_info(
- cr, uid, [move_line.id],
- account_ids and account_ids[0] or False),
- trans2)
+ return (trans, self._get_move_info(
+ cr, uid, [move_line.id],
+ account_ids and account_ids[0] or False),
+ trans2)
return trans, False, False
@@ -791,7 +791,7 @@ class banking_import_transaction(orm.Model):
if move_lines and len(move_lines) == 1:
retval['reference'] = move_lines[0].ref
if retval['match_type'] == 'invoice':
- retval['invoice_ids'] = [x.invoice.id for x in move_lines]
+ retval['invoice_ids'] = list(set([x.invoice.id for x in move_lines]))
retval['type'] = type_map[move_lines[0].invoice.type]
return retval
@@ -826,7 +826,8 @@ class banking_import_transaction(orm.Model):
journal_obj = self.pool.get('account.journal')
move_line_obj = self.pool.get('account.move.line')
payment_line_obj = self.pool.get('payment.line')
- has_payment = bool(payment_line_obj)
+ has_payment = bool(
+ payment_line_obj and 'date_done' in payment_line_obj._columns)
statement_line_obj = self.pool.get('account.bank.statement.line')
statement_obj = self.pool.get('account.bank.statement')
imported_statement_ids = []
@@ -862,8 +863,6 @@ class banking_import_transaction(orm.Model):
('date_done', '=', False)], context=context)
payment_lines = payment_line_obj.browse(
cr, uid, payment_line_ids)
- else:
- payment_lines = False
# Start the loop over the transactions requested to match
transactions = self.browse(cr, uid, ids, context)
@@ -891,6 +890,9 @@ class banking_import_transaction(orm.Model):
i += 1
continue
+ partner_banks = []
+ partner_ids = []
+
# TODO: optimize by ordering transactions per company,
# and perform the stanza below only once per company.
# In that case, take newest transaction date into account
@@ -1044,7 +1046,6 @@ class banking_import_transaction(orm.Model):
if not [x for x in move_lines if x.id == line.id]:
move_lines.append(line)
partner_ids = [account_info.bank_partner_id.id]
- partner_banks = []
else:
# Link remote partner, import account when needed
partner_banks = banktools.get_bank_accounts(
@@ -1054,47 +1055,28 @@ class banking_import_transaction(orm.Model):
if partner_banks:
partner_ids = [x.partner_id.id for x in partner_banks]
elif transaction.remote_owner:
- iban = sepa.IBAN(transaction.remote_account)
- if iban.valid:
- country_code = iban.countrycode
- elif transaction.remote_owner_country_code:
- country_code = transaction.remote_owner_country_code
- # fallback on the import parsers country code
- elif transaction.bank_country_code:
- country_code = transaction.bank_country_code
- elif company.partner_id and company.partner_id.country:
- country_code = company.partner_id.country.code
- else:
- country_code = None
- partner_id = banktools.get_or_create_partner(
+ country_id = banktools.get_country_id(
+ self.pool, cr, uid, transaction, context=context)
+ partner_id = banktools.get_partner(
self.pool, cr, uid, transaction.remote_owner,
transaction.remote_owner_address,
transaction.remote_owner_postalcode,
transaction.remote_owner_city,
- country_code, results['log'],
- customer=transaction.transferred_amount > 0,
- supplier=transaction.transferred_amount < 0,
+ country_id, results['log'],
context=context)
- if transaction.remote_account:
- partner_bank_id = banktools.create_bank_account(
- self.pool, cr, uid, partner_id,
- transaction.remote_account,
- transaction.remote_owner,
- transaction.remote_owner_address,
- transaction.remote_owner_city,
- country_code, results['log'],
- bic=transaction.remote_bank_bic
- )
- partner_banks = partner_bank_obj.browse(
- cr, uid, [partner_bank_id]
- )
- else:
- partner_bank_id = None
- partner_banks = []
- partner_ids = [partner_id]
- else:
- partner_ids = []
- partner_banks = []
+ if partner_id:
+ partner_ids = [partner_id]
+ if transaction.remote_account:
+ partner_bank_id = banktools.create_bank_account(
+ self.pool, cr, uid, partner_id,
+ transaction.remote_account,
+ transaction.remote_owner,
+ transaction.remote_owner_address,
+ transaction.remote_owner_city,
+ country_id, bic=transaction.remote_bank_bic,
+ context=context)
+ partner_banks = partner_bank_obj.browse(
+ cr, uid, [partner_bank_id], context=context)
# Credit means payment... isn't it?
if (not move_info
@@ -1300,6 +1282,21 @@ class banking_import_transaction(orm.Model):
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',
@@ -1351,7 +1348,7 @@ class banking_import_transaction(orm.Model):
'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',
ondelete='CASCADE'),
@@ -1420,10 +1417,28 @@ banking_import_transaction()
class account_bank_statement_line(orm.Model):
_inherit = 'account.bank.statement.line'
+
+ def _get_link_partner_ok(
+ self, cr, uid, ids, name, args, context=None):
+ """
+ Deliver the values of the function field that
+ determines if the 'link partner' wizard is show on the
+ bank statement line
+ """
+ res = {}
+ for line in self.browse(cr, uid, ids, context):
+ res[line.id] = bool(
+ line.state == 'draft'
+ and not line.partner_id
+ and line.import_transaction_id
+ and line.import_transaction_id.remote_owner
+ and line.import_transaction_id.remote_account)
+ return res
+
_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),
@@ -1450,6 +1465,11 @@ class account_bank_statement_line(orm.Model):
'state': fields.selection(
[('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State',
readonly=True, required=True),
+ 'parent_id': fields.many2one('account.bank.statement.line',
+ 'Parent'),
+ 'link_partner_ok': fields.function(
+ _get_link_partner_ok, type='boolean',
+ string='Can link partner'),
}
_defaults = {
@@ -1470,6 +1490,66 @@ class account_bank_statement_line(orm.Model):
res = wizard_obj.create_act_window(cr, uid, res_id, context=context)
return res
+ def link_partner(self, cr, uid, ids, context=None):
+ """
+ Get the appropriate partner or fire a wizard to create
+ or link one
+ """
+ if not ids:
+ return False
+
+ if isinstance(ids, (int, long)):
+ ids = [ids]
+
+ # Check if the partner is already known but not shown
+ # because the screen was not refreshed yet
+ statement_line = self.browse(
+ cr, uid, ids[0], context=context)
+ if statement_line.partner_id:
+ return True
+
+ # Reuse the bank's partner if any
+ if (statement_line.partner_bank_id and
+ statement_line.partner_bank_id.partner_id):
+ statement_line.write(
+ {'partner_id': statement_line.partner_bank_id.partner_id.id})
+ return True
+
+ if (not statement_line.import_transaction_id or
+ not statement_line.import_transaction_id.remote_account):
+ raise osv.except_osv(
+ _("Error"),
+ _("No bank account available to link partner to"))
+
+ # Check if the bank account was already been linked
+ # manually to another transaction
+ remote_account = statement_line.import_transaction_id.remote_account
+ source_line_ids = self.search(
+ cr, uid,
+ [('import_transaction_id.remote_account', '=', remote_account),
+ ('partner_bank_id.partner_id', '!=', False),
+ ], limit=1, context=context)
+ if source_line_ids:
+ source_line = self.browse(
+ cr, uid, source_line_ids[0], context=context)
+ target_line_ids = self.search(
+ cr, uid,
+ [('import_transaction_id.remote_account', '=', remote_account),
+ ('partner_bank_id', '=', False),
+ ('state', '=', 'draft')], context=context)
+ self.write(
+ cr, uid, target_line_ids,
+ {'partner_bank_id': source_line.partner_bank_id.id,
+ 'partner_id': source_line.partner_bank_id.partner_id.id,
+ }, context=context)
+ return True
+
+ # Or fire the wizard to link partner and account
+ wizard_obj = self.pool.get('banking.link_partner')
+ res_id = wizard_obj.create(
+ cr, uid, {'statement_line_id': ids[0]}, context=context)
+ return wizard_obj.create_act_window(cr, uid, res_id, context=context)
+
def _convert_currency(
self, cr, uid, from_curr_id, to_curr_id, from_amount,
round=False, date=None, context=None):
@@ -1590,6 +1670,8 @@ class account_bank_statement_line(orm.Model):
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]
@@ -1599,6 +1681,12 @@ class account_bank_statement_line(orm.Model):
_('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)
@@ -1638,7 +1726,45 @@ class account_bank_statement_line(orm.Model):
'import_transaction_id': res},
context=context)
-account_bank_statement_line()
+ 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
+
+ child_statement_ids.append(
+ self.create(cr, uid, statement_line_data,
+ context=context))
+ this.write({'amount': this.amount - amount})
+
+ return child_statement_ids
class account_bank_statement(orm.Model):
diff --git a/account_banking/static/src/js/account_banking.js b/account_banking/static/src/js/account_banking.js
new file mode 100644
index 000000000..93ef30a41
--- /dev/null
+++ b/account_banking/static/src/js/account_banking.js
@@ -0,0 +1,61 @@
+/*############################################################################
+#
+# Copyright (C) 2013 Therp BV ().
+#
+# 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 .
+#
+############################################################################*/
+
+openerp.account_banking = function(instance)
+{
+ var _t = instance.web._t;
+ instance.web.Dialog.include(
+ {
+ close: function()
+ {
+ this._super.apply(this, arguments);
+ if (this.dialog_title == _t("Match transaction"))
+ {
+ // The match wizard can create or unlink a statement line
+ // Force a reload of the view so that the correct lines
+ // are shown.
+ var parent = this.getParent()
+ if (parent)
+ {
+ var child = this.getParent().getChildren()[0];
+ if (child.views) {
+ _.each(child.views, function(view)
+ {
+ if (view && view.controller)
+ {
+ view.controller.reload();
+ }
+ }
+ );
+ }
+ }
+ }
+ },
+ });
+}
diff --git a/account_banking/wizard/__init__.py b/account_banking/wizard/__init__.py
index 7c98ca7b2..169e55e51 100644
--- a/account_banking/wizard/__init__.py
+++ b/account_banking/wizard/__init__.py
@@ -20,5 +20,6 @@
##############################################################################
import bank_import
import banking_transaction_wizard
+import link_partner
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/account_banking/wizard/banking_transaction_wizard.py b/account_banking/wizard/banking_transaction_wizard.py
index 4bc9a1954..bdd5ed471 100644
--- a/account_banking/wizard/banking_transaction_wizard.py
+++ b/account_banking/wizard/banking_transaction_wizard.py
@@ -73,7 +73,7 @@ class banking_transaction_wizard(orm.TransientModel):
Call the automatic matching routine for one or
more bank transactions
"""
- if isinstance(ids, (int, float)):
+ if isinstance(ids, (int, long)):
ids = [ids]
import_transaction_obj = self.pool.get('banking.import.transaction')
trans_id = self.read(
@@ -98,6 +98,8 @@ class banking_transaction_wizard(orm.TransientModel):
# 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', [])
res = super(banking_transaction_wizard, self).write(
cr, uid, ids, vals, context=context)
@@ -143,55 +145,96 @@ class banking_transaction_wizard(orm.TransientModel):
_("No entry found for the selected invoice. " +
"Try manual reconciliation."))
- if manual_move_line_id or manual_invoice_id:
+ if manual_move_line_id or manual_invoice_id \
+ or 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 = (
+ ([manual_invoice_id] if manual_invoice_id else []) +
+ [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 = (
+ ([manual_move_line_id] if manual_move_line_id else []) +
+ [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:
- orm.except_orm(
+ if not found_move_line:
+ raise orm.except_orm(
_("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):
@@ -207,7 +250,7 @@ class banking_transaction_wizard(orm.TransientModel):
settings_pool = self.pool.get('account.banking.account.settings')
statement_pool = self.pool.get('account.bank.statement.line')
- if isinstance(ids, (int, float)):
+ if isinstance(ids, (int, long)):
ids = [ids]
for wiz in self.browse(cr, uid, ids, context=context):
@@ -223,18 +266,24 @@ class banking_transaction_wizard(orm.TransientModel):
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 self.create_act_window(cr, uid, ids, context=None)
def reverse_duplicate(self, cr, uid, ids, context=None):
- if isinstance(ids, (int, float)):
+ if isinstance(ids, (int, long)):
ids = [ids]
transaction_obj = self.pool.get('banking.import.transaction')
for wiz in self.read(
@@ -246,7 +295,7 @@ class banking_transaction_wizard(orm.TransientModel):
return self.create_act_window(cr, uid, ids, context=None)
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'}
_columns = {
'name': fields.char('Name', size=64),
@@ -266,6 +315,9 @@ class banking_transaction_wizard(orm.TransientModel):
'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",
@@ -277,10 +329,6 @@ class banking_transaction_wizard(orm.TransientModel):
'import_transaction_id', 'writeoff_account_id',
type='many2one', relation='account.account',
string='Write-off account'),
- 'writeoff_journal_id': fields.related(
- 'import_transaction_id', 'writeoff_journal_id',
- type='many2one', relation='account.journal',
- string='Write-off journal'),
'invoice_ids': fields.related(
'import_transaction_id', 'invoice_ids', string="Matching invoices",
type='many2many', relation='account.invoice'),
@@ -318,8 +366,18 @@ class banking_transaction_wizard(orm.TransientModel):
'manual_move_line_id': fields.many2one(
'account.move.line', 'Or match this entry',
domain=[('account_id.reconcile', '=', True),
- ('reconcile_id', '=', False)],
- ),
+ ('reconcile_id', '=', False)]),
+ 'manual_invoice_ids': fields.many2many(
+ 'account.invoice',
+ 'banking_transaction_wizard_account_invoice_rel',
+ 'wizard_id', 'invoice_id', string='Match following invoices',
+ domain=[('reconciled', '=', False)]),
+ 'manual_move_line_ids': fields.many2many(
+ 'account.move.line',
+ 'banking_transaction_wizard_account_move_line_rel',
+ 'wizard_id', 'move_line_id', string='Or match this entries',
+ domain=[('account_id.reconcile', '=', True),
+ ('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(
diff --git a/account_banking/wizard/banking_transaction_wizard.xml b/account_banking/wizard/banking_transaction_wizard.xml
index 561feb049..e65d3ac4c 100644
--- a/account_banking/wizard/banking_transaction_wizard.xml
+++ b/account_banking/wizard/banking_transaction_wizard.xml
@@ -7,6 +7,7 @@