mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
[ADD] Move voucher logic from statement line to the transaction level
Preserve legacy methods for canceling reconciliation oriented transactions
This commit is contained in:
@@ -534,9 +534,16 @@ class banking_import_transaction(osv.osv):
|
||||
uid, 'account.invoice', move_line.invoice.id, 'undo_paid', cr)
|
||||
return True
|
||||
|
||||
def _reconcile_move(
|
||||
self, cr, uid, transaction_id, context=None):
|
||||
transaction = self.browse(cr, uid, transaction_id, context=context)
|
||||
def _create_voucher_move(self, cr, uid, transaction_id, context=None):
|
||||
"""
|
||||
The line is matched against a move (invoice), so generate a payment voucher with the write-off settings that the
|
||||
user requested. The move lines will be generated by the voucher, handling rounding and currency conversion.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
statement_line_pool = self.pool.get('account.bank.statement.line')
|
||||
transaction = self.browse(cr, uid, transaction_id, context)
|
||||
if not transaction.move_line_id:
|
||||
if transaction.match_type == 'invoice':
|
||||
raise osv.except_osv(
|
||||
@@ -558,6 +565,87 @@ class banking_import_transaction(osv.osv):
|
||||
transaction.statement_line_id.statement_id.name,
|
||||
transaction.statement_line_id.name
|
||||
)))
|
||||
|
||||
st_line = transaction.statement_line_id
|
||||
journal = st_line.statement_id.journal_id
|
||||
if st_line.amount < 0.0:
|
||||
voucher_type = 'payment'
|
||||
account_id = (journal.default_debit_account_id and
|
||||
journal.default_debit_account_id.id or False)
|
||||
else:
|
||||
voucher_type = 'receipt'
|
||||
account_id = (journal.default_credit_account_id and
|
||||
journal.default_credit_account_id.id or False)
|
||||
|
||||
# Use the statement line's date determine the period
|
||||
ctxt = context.copy()
|
||||
ctxt['company_id'] = st_line.company_id.id
|
||||
if 'period_id' in ctxt:
|
||||
del ctxt['period_id']
|
||||
period_id = self.pool.get('account.period').find(
|
||||
cr, uid, st_line.date, context=ctxt)[0]
|
||||
|
||||
# Convert the move line amount to the journal currency
|
||||
move_line_amount = transaction.move_line_id.amount_residual_currency
|
||||
to_curr_id = (st_line.statement_id.journal_id.currency and
|
||||
st_line.statement_id.journal_id.currency.id or
|
||||
st_line.statement_id.company_id.currency_id.id)
|
||||
from_curr_id = (transaction.move_line_id.currency_id and
|
||||
transaction.move_line_id.currency_id.id or
|
||||
st_line.statement_id.company_id.currency_id.id)
|
||||
if from_curr_id != to_curr_id:
|
||||
amount_currency = statement_line_pool._convert_currency(
|
||||
cr, uid, from_curr_id, to_curr_id, move_line_amount,
|
||||
round=True, date=time.strftime('%Y-%m-%d'),
|
||||
context=context)
|
||||
else:
|
||||
amount_currency = move_line_amount
|
||||
|
||||
# Check whether this is a full or partial reconciliation
|
||||
if transaction.payment_option=='with_writeoff':
|
||||
writeoff = abs(st_line.amount)-abs(amount_currency)
|
||||
line_amount = abs(amount_currency)
|
||||
else:
|
||||
writeoff = 0.0
|
||||
line_amount = abs(st_line.amount)
|
||||
|
||||
# Define the voucher
|
||||
voucher = {
|
||||
'journal_id': st_line.statement_id.journal_id.id,
|
||||
'partner_id': st_line.partner_id and st_line.partner_id.id or False,
|
||||
'company_id': st_line.company_id.id,
|
||||
'type':voucher_type,
|
||||
'company_id': st_line.company_id.id,
|
||||
'account_id': account_id,
|
||||
'amount': abs(st_line.amount),
|
||||
'writeoff_amount': writeoff,
|
||||
'payment_option': transaction.payment_option,
|
||||
'writeoff_acc_id': transaction.writeoff_account_id.id,
|
||||
'analytic_id': transaction.writeoff_analytic_id.id,
|
||||
'date': st_line.date,
|
||||
'date_due': st_line.date,
|
||||
'period_id': period_id,
|
||||
'payment_rate_currency_id':to_curr_id,
|
||||
}
|
||||
|
||||
# Define the voucher line
|
||||
vch_line = {
|
||||
#'voucher_id': v_id,
|
||||
'move_line_id': transaction.move_line_id.id,
|
||||
'reconcile': True,
|
||||
'amount': line_amount,
|
||||
'account_id': transaction.move_line_id.account_id.id,
|
||||
'type': transaction.move_line_id.credit and 'dr' or 'cr',
|
||||
}
|
||||
voucher['line_ids'] = [(0,0,vch_line)]
|
||||
v_id = self.pool.get('account.voucher').create(
|
||||
cr, uid, voucher, context=context)
|
||||
|
||||
return v_id
|
||||
|
||||
def _reconcile_move(
|
||||
self, cr, uid, transaction_id, context=None):
|
||||
transaction = self.browse(cr, uid, transaction_id, context=context)
|
||||
currency = transaction.statement_line_id.statement_id.currency
|
||||
line_ids = [transaction.move_line_id.id]
|
||||
if transaction.writeoff_move_line_id:
|
||||
@@ -653,20 +741,101 @@ class banking_import_transaction(osv.osv):
|
||||
transaction.statement_line_id.amount,
|
||||
transaction.statement_line_id.currency)
|
||||
|
||||
def _cancel_move(
|
||||
self, cr, uid, transaction_id, context=None):
|
||||
statement_line_obj = self.pool.get('account.bank.statement.line')
|
||||
transaction = self.browse(cr, uid, transaction_id, context=context)
|
||||
def _legacy_do_move_unreconcile(self, cr, uid, move_line_ids, currency, context=None):
|
||||
"""
|
||||
Legacy method. Allow for canceling bank statement lines that
|
||||
were confirmed using earlier versions of the interactive wizard branch.
|
||||
|
||||
Undo a reconciliation, removing the given move line ids. If no
|
||||
meaningful (partial) reconciliation remains, delete it.
|
||||
|
||||
:param move_line_ids: List of ids. This will usually be the move
|
||||
line of an associated invoice or payment, plus optionally the
|
||||
move line of a writeoff.
|
||||
:param currency: A res.currency *browse* object to perform math
|
||||
operations on the amounts.
|
||||
"""
|
||||
|
||||
move_line_obj = self.pool.get('account.move.line')
|
||||
reconcile_obj = self.pool.get('account.move.reconcile')
|
||||
is_zero = lambda amount: self.pool.get('res.currency').is_zero(
|
||||
cr, uid, currency, amount)
|
||||
move_lines = move_line_obj.browse(cr, uid, move_line_ids, context=context)
|
||||
reconcile = move_lines[0].reconcile_id or move_lines[0].reconcile_partial_id
|
||||
line_ids = [x.id for x in reconcile.line_id or reconcile.line_partial_ids]
|
||||
for move_line_id in move_line_ids:
|
||||
line_ids.remove(move_line_id)
|
||||
if len(line_ids) > 1:
|
||||
full = is_zero(move_line_obj.get_balance(cr, uid, line_ids))
|
||||
if full:
|
||||
line_partial_ids = []
|
||||
else:
|
||||
line_partial_ids = list(line_ids)
|
||||
line_ids = []
|
||||
reconcile_obj.write(
|
||||
cr, uid, reconcile.id,
|
||||
{ 'line_partial_ids': [(6, 0, line_partial_ids)],
|
||||
'line_id': [(6, 0, line_ids)],
|
||||
}, context=context)
|
||||
else:
|
||||
reconcile_obj.unlink(cr, uid, reconcile.id, context=context)
|
||||
for move_line in move_lines:
|
||||
if move_line.invoice:
|
||||
# reopening the invoice
|
||||
netsvc.LocalService('workflow').trg_validate(
|
||||
uid, 'account.invoice', move_line.invoice.id, 'undo_paid', cr)
|
||||
return True
|
||||
|
||||
def _legacy_clear_up_writeoff(self, cr, uid, transaction, context=None):
|
||||
"""
|
||||
Legacy method to support upgrades older installations of the
|
||||
interactive wizard branch. To be removed after 6.2
|
||||
clear up the writeoff move
|
||||
"""
|
||||
if transaction.writeoff_move_line_id:
|
||||
move_obj.button_cancel(
|
||||
cr, uid, [transaction.writeoff_move_line_id.move_id.id],
|
||||
context=context)
|
||||
move_obj.unlink(
|
||||
cr, uid, [transaction.writeoff_move_line_id.move_id.id],
|
||||
context=context)
|
||||
return True
|
||||
|
||||
def _legacy_cancel_move(
|
||||
self, cr, uid, transaction, context=None):
|
||||
"""
|
||||
Legacy method to support upgrades from older installations
|
||||
of the interactive wizard branch.
|
||||
"""
|
||||
move_line_id = transaction.move_line_id.id
|
||||
currency = transaction.statement_line_id.statement_id.currency
|
||||
line_ids = [transaction.move_line_id.id]
|
||||
if transaction.writeoff_move_line_id:
|
||||
line_ids.append(transaction.writeoff_move_line_id.id)
|
||||
self._do_move_unreconcile(
|
||||
self._legacy_do_move_unreconcile(
|
||||
cr, uid, line_ids, currency, context=context)
|
||||
statement_line_obj.write(
|
||||
cr, uid, transaction.statement_line_id.id,
|
||||
{'reconcile_id': False}, context=context)
|
||||
|
||||
def _cancel_voucher(
|
||||
self, cr, uid, transaction_id, context=None):
|
||||
voucher_pool = self.pool.get('account.voucher')
|
||||
transaction = self.browse(cr, uid, transaction_id, context=context)
|
||||
st_line = transaction.statement_line_id
|
||||
if transaction.match_type:
|
||||
if st_line.voucher_id:
|
||||
# Cancel and delete the vouchers
|
||||
voucher_pool.cancel_voucher(
|
||||
cr, uid, [st_line.voucher_id.id], context=context)
|
||||
voucher_pool.action_cancel_draft(
|
||||
cr, uid, [st_line.voucher_id.id], context=context)
|
||||
voucher_pool.unlink(
|
||||
cr, uid, [st_line.voucher_id.id], context=context)
|
||||
# Allow canceling of legacy entries
|
||||
elif st_line.reconcile_id:
|
||||
self._legacy_cancel_move(cr, uid, transaction, context=context)
|
||||
|
||||
return True
|
||||
|
||||
def _cancel_storno(
|
||||
@@ -724,12 +893,13 @@ class banking_import_transaction(osv.osv):
|
||||
|
||||
cancel_map = {
|
||||
'storno': _cancel_storno,
|
||||
'invoice': _cancel_move,
|
||||
'manual': _cancel_move,
|
||||
'move': _cancel_move,
|
||||
'invoice': _cancel_voucher,
|
||||
'manual': _cancel_voucher,
|
||||
'move': _cancel_voucher,
|
||||
'payment_order': _cancel_payment_order,
|
||||
'payment': _cancel_payment,
|
||||
}
|
||||
|
||||
def cancel(self, cr, uid, ids, context=None):
|
||||
if ids and isinstance(ids, (int, float)):
|
||||
ids = [ids]
|
||||
@@ -743,31 +913,33 @@ class banking_import_transaction(osv.osv):
|
||||
_("No method found to cancel this type"))
|
||||
self.cancel_map[transaction.match_type](
|
||||
self, cr, uid, transaction.id, context)
|
||||
# clear up the writeoff move
|
||||
if transaction.writeoff_move_line_id:
|
||||
move_obj.button_cancel(
|
||||
cr, uid, [transaction.writeoff_move_line_id.move_id.id],
|
||||
context=context)
|
||||
move_obj.unlink(
|
||||
cr, uid, [transaction.writeoff_move_line_id.move_id.id],
|
||||
context=context)
|
||||
self._legacy_clear_up_writeoff(cr, uid, transaction, context=context)
|
||||
if transaction.statement_line_id.move_id:
|
||||
# We allow for people canceling and removing
|
||||
# the associated payments, which can lead to confirmed
|
||||
# statement lines without an associated move
|
||||
account_move_obj.button_cancel(
|
||||
cr, uid, [transaction.statement_line_id.move_id], context)
|
||||
account_move_obj.unlink(
|
||||
cr, uid, [transaction.statement_line_id.move_id], context)
|
||||
return True
|
||||
|
||||
reconcile_map = {
|
||||
'storno': _reconcile_storno,
|
||||
'invoice': _reconcile_move,
|
||||
'manual': _reconcile_move,
|
||||
'payment_order': _reconcile_payment_order,
|
||||
'payment': _reconcile_payment,
|
||||
'move': _reconcile_move,
|
||||
create_voucher_map = {
|
||||
# 'storno': _create_voucher_storno,
|
||||
'invoice': _create_voucher_move,
|
||||
'manual': _create_voucher_move,
|
||||
# 'payment_order': _create_voucher_payment_order,
|
||||
# 'payment': _create_voucher_payment,
|
||||
'move': _create_voucher_move,
|
||||
}
|
||||
def reconcile(self, cr, uid, ids, context=None):
|
||||
|
||||
def create_voucher(self, cr, uid, ids, context=None):
|
||||
if ids and isinstance(ids, (int, float)):
|
||||
ids = [ids]
|
||||
for transaction in self.browse(cr, uid, ids, context):
|
||||
if not transaction.match_type:
|
||||
continue
|
||||
if transaction.match_type not in self.reconcile_map:
|
||||
if transaction.match_type not in self.create_voucher_map:
|
||||
raise osv.except_osv(
|
||||
_("Cannot reconcile"),
|
||||
_("Cannot reconcile type %s. No method found to " +
|
||||
@@ -782,14 +954,11 @@ class banking_import_transaction(osv.osv):
|
||||
"this match type.") %
|
||||
transaction.statement_line_id.name
|
||||
)
|
||||
self._generate_writeoff_move(
|
||||
cr, uid, transaction.id, context=context)
|
||||
# run the method that is appropriate for this match type
|
||||
reconcile_id = self.reconcile_map[transaction.match_type](
|
||||
voucher_id = self.create_voucher_map[transaction.match_type](
|
||||
self, cr, uid, transaction.id, context)
|
||||
self.pool.get('account.bank.statement.line').write(
|
||||
cr, uid, transaction.statement_line_id.id,
|
||||
{'reconcile_id': reconcile_id}, context=context)
|
||||
{'voucher_id': voucher_id}, context=context)
|
||||
|
||||
# TODO
|
||||
# update the statement line bank account reference
|
||||
@@ -802,64 +971,7 @@ class banking_import_transaction(osv.osv):
|
||||
][0]
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
def _generate_writeoff_move(self, cr, uid, ids, context):
|
||||
if ids and isinstance(ids, (int, float)):
|
||||
ids = [ids]
|
||||
move_line_obj = self.pool.get('account.move.line')
|
||||
move_obj = self.pool.get('account.move')
|
||||
for trans in self.browse(cr, uid, ids, context=context):
|
||||
# Get the period for the company and date
|
||||
ctxt = context.copy()
|
||||
ctxt['company_id'] = trans.company_id.id
|
||||
periods = self.pool.get('account.period').find(
|
||||
cr, uid, trans.statement_line_id.date, context=ctxt)
|
||||
period_id = periods and periods[0] or False
|
||||
|
||||
move_id = move_obj.create(cr, uid, {
|
||||
'journal_id': trans.writeoff_journal_id.id,
|
||||
'period_id': period_id,
|
||||
'date': trans.statement_line_id.date,
|
||||
'name': '(write-off) %s' % (
|
||||
trans.move_line_id.move_id.name or ''),
|
||||
}, context=context)
|
||||
if trans.residual > 0:
|
||||
writeoff_debit = trans.residual
|
||||
writeoff_credit = False
|
||||
else:
|
||||
writeoff_debit = False
|
||||
writeoff_credit = - trans.residual
|
||||
vals = {
|
||||
'name': trans.statement_line_id.name,
|
||||
'date': trans.statement_line_id.date,
|
||||
'ref': trans.statement_line_id.ref,
|
||||
'move_id': move_id,
|
||||
'partner_id': (trans.statement_line_id.partner_id and
|
||||
trans.statement_line_id.partner_id.id or False),
|
||||
'account_id': trans.statement_line_id.account_id.id,
|
||||
'credit': writeoff_debit,
|
||||
'debit': writeoff_credit,
|
||||
'journal_id': trans.writeoff_journal_id.id,
|
||||
'period_id': period_id,
|
||||
'currency_id': trans.statement_line_id.statement_id.currency.id,
|
||||
'analytic_account_id': trans.writeoff_analytic_id.id,
|
||||
}
|
||||
move_line_id = move_line_obj.create(
|
||||
cr, uid, vals, context=context)
|
||||
self.write(
|
||||
cr, uid, trans.id,
|
||||
{'writeoff_move_line_id': move_line_id}, context=context)
|
||||
vals.update({
|
||||
'account_id': trans.writeoff_account_id.id,
|
||||
'credit': writeoff_credit,
|
||||
'debit': writeoff_debit,
|
||||
})
|
||||
move_line_obj.create(
|
||||
cr, uid, vals, context=context)
|
||||
move_obj.post(
|
||||
cr, uid, [move_id], context=context)
|
||||
|
||||
|
||||
def _match_storno(
|
||||
self, cr, uid, trans, log, context=None):
|
||||
payment_line_obj = self.pool.get('payment.line')
|
||||
@@ -1618,9 +1730,20 @@ class banking_import_transaction(osv.osv):
|
||||
'writeoff_account_id': fields.many2one(
|
||||
'account.account', 'Write-off account',
|
||||
domain=[('type', '!=', 'view')]),
|
||||
'payment_option':fields.selection([('without_writeoff', 'Keep Open'),('with_writeoff', 'Reconcile Payment Balance')], 'Payment Difference',
|
||||
required=True, help="This field helps you to choose what you want to do with the eventual difference between the paid amount and the sum of allocated amounts. You can either choose to keep open this difference on the partner's account, or reconcile it with the payment(s)"),
|
||||
'payment_option':fields.selection(
|
||||
[
|
||||
('without_writeoff', 'Keep Open'),
|
||||
('with_writeoff', 'Reconcile Payment Balance')
|
||||
], 'Payment Difference',
|
||||
required=True,
|
||||
help=("This field helps you to choose what you want to do with "
|
||||
"the eventual difference between the paid amount and the "
|
||||
"sum of allocated amounts. You can either choose to keep "
|
||||
"open this difference on the partner's account, "
|
||||
"or reconcile it with the payment(s)"),
|
||||
),
|
||||
'writeoff_amount': fields.float('Difference Amount'),
|
||||
# Legacy field: to be removed after 6.2
|
||||
'writeoff_move_line_id': fields.many2one(
|
||||
'account.move.line', 'Write off move line'),
|
||||
'writeoff_analytic_id': fields.many2one(
|
||||
@@ -1690,8 +1813,9 @@ class account_bank_statement_line(osv.osv):
|
||||
res = wizard_obj.create_act_window(cr, uid, res_id, context=context)
|
||||
return res
|
||||
|
||||
|
||||
def _convert_currency(self, cr, uid, from_curr_id, to_curr_id, from_amount, round=False, date=None, context=None):
|
||||
def _convert_currency(
|
||||
self, cr, uid, from_curr_id, to_curr_id, from_amount,
|
||||
round=False, date=None, context=None):
|
||||
"""Convert currency amount using the company rate on a specific date"""
|
||||
curr_obj = self.pool.get('res.currency')
|
||||
if context:
|
||||
@@ -1701,10 +1825,11 @@ class account_bank_statement_line(osv.osv):
|
||||
if date:
|
||||
ctxt["date"] = date
|
||||
|
||||
amount = curr_obj.compute(cr, uid, from_curr_id, to_curr_id, from_amount, round=round, context=ctxt)
|
||||
amount = curr_obj.compute(
|
||||
cr, uid, from_curr_id, to_curr_id, from_amount,
|
||||
round=round, context=ctxt)
|
||||
return amount
|
||||
|
||||
|
||||
def confirm(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Create (or update) a voucher for each statement line, and then generate
|
||||
@@ -1716,6 +1841,7 @@ class account_bank_statement_line(osv.osv):
|
||||
statement_pool = self.pool.get('account.bank.statement')
|
||||
obj_seq = self.pool.get('ir.sequence')
|
||||
move_pool = self.pool.get('account.move')
|
||||
import_transaction_obj = self.pool.get('banking.import.transaction')
|
||||
|
||||
for st_line in self.browse(cr, uid, ids, context):
|
||||
if st_line.state != 'draft':
|
||||
@@ -1747,10 +1873,15 @@ class account_bank_statement_line(osv.osv):
|
||||
st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement')
|
||||
statement_obj.write(cr, uid, [st.id], {'name': st_number}, context=context)
|
||||
|
||||
# Check if this line has been matched against a journal item
|
||||
if st_line.import_transaction_id.move_line_id:
|
||||
if st_line.import_transaction_id:
|
||||
import_transaction_obj.create_voucher(
|
||||
cr, uid, st_line.import_transaction_id.id, context)
|
||||
st_line.refresh()
|
||||
if st_line.voucher_id:
|
||||
|
||||
# Check if this line has been matched against a journal item
|
||||
# Line has been matched, so post it via a voucher
|
||||
self._post_with_voucher(cr, uid, ids, st_line, voucher_pool, move_pool, context=context)
|
||||
self._post_voucher(cr, uid, ids, st_line, move_pool, context=context)
|
||||
|
||||
else:
|
||||
# Check to see if the line has an account that can be used to generate a journal entry
|
||||
@@ -1776,104 +1907,18 @@ class account_bank_statement_line(osv.osv):
|
||||
self.write(cr, uid, st_line.id, {'state': 'confirmed', 'move_id': move_id}, context)
|
||||
|
||||
|
||||
def _post_with_voucher(self, cr, uid, ids, st_line, voucher_pool, move_pool, context):
|
||||
# Check if a voucher has already been created
|
||||
if st_line.voucher_id:
|
||||
# There's an existing voucher on the statement line which was probably created
|
||||
# manually. This may have been done because it was a single payment for multiple
|
||||
# invoices. Just get the voucher ID.
|
||||
voucher_id = st_line.voucher_id.id
|
||||
else:
|
||||
# Create a voucher and store the ID on the statement line
|
||||
voucher_id = self._create_voucher(cr, uid, ids, st_line, context=context)
|
||||
self.pool.get('account.bank.statement.line').write(cr,uid,st_line.id,{'voucher_id':voucher_id} , context=context)
|
||||
|
||||
def _post_voucher(self, cr, uid, ids, st_line, move_pool, context):
|
||||
# If the voucher is in draft mode, then post it
|
||||
voucher = voucher_pool.browse(cr, uid, voucher_id, context=context)
|
||||
if voucher.state in ('draft','proforma'):
|
||||
voucher.action_move_line_create()
|
||||
|
||||
if st_line.voucher_id.state in ('draft','proforma'):
|
||||
st_line.voucher_id.action_move_line_create()
|
||||
st_line.voucher_id.refresh()
|
||||
# Update the statement line to indicate that it has been posted
|
||||
# ... no longer need to set the move_id on the voucher?
|
||||
self.write(cr, uid, st_line.id, {'state': 'confirmed'}, context)
|
||||
|
||||
# The voucher journal isn't automatically posted, so post it (if needed)
|
||||
if not voucher.journal_id.entry_posted:
|
||||
voucher = voucher_pool.browse(cr, uid, voucher_id, context=context)
|
||||
move_pool.post(cr, uid, [voucher.move_id.id], context={})
|
||||
|
||||
|
||||
def _create_voucher(self, cr, uid, ids, st_line, context):
|
||||
"""
|
||||
The line is matched against a move (invoice), so generate a payment voucher with the write-off settings that the
|
||||
user requested. The move lines will be generated by the voucher, handling rounding and currency conversion.
|
||||
"""
|
||||
journal = st_line.statement_id.journal_id
|
||||
if st_line.amount < 0.0:
|
||||
voucher_type = 'payment'
|
||||
account_id = journal.default_debit_account_id and journal.default_debit_account_id.id or False
|
||||
else:
|
||||
voucher_type = 'receipt'
|
||||
account_id = journal.default_credit_account_id and journal.default_credit_account_id.id or False
|
||||
|
||||
# Use the statement line's date determine the period
|
||||
ctxt = context.copy()
|
||||
ctxt['company_id'] = st_line.company_id.id
|
||||
if 'period_id' in ctxt:
|
||||
del ctxt['period_id']
|
||||
period_id = self.pool.get('account.period').find(cr, uid, st_line.date, context=ctxt)[0]
|
||||
|
||||
# Convert the move line amount to the journal currency
|
||||
move_line_amount = st_line.import_transaction_id.move_line_id.amount_residual_currency
|
||||
to_curr_id = st_line.statement_id.journal_id.currency and st_line.statement_id.journal_id.currency.id or st_line.statement_id.company_id.currency_id.id
|
||||
from_curr_id = st_line.import_transaction_id.move_line_id.currency_id and st_line.import_transaction_id.move_line_id.currency_id.id or st_line.statement_id.company_id.currency_id.id
|
||||
if from_curr_id != to_curr_id:
|
||||
amount_currency = self._convert_currency(cr, uid, from_curr_id, to_curr_id, move_line_amount, round=True,
|
||||
date=time.strftime('%Y-%m-%d'), context=context)
|
||||
else:
|
||||
amount_currency = move_line_amount
|
||||
|
||||
# Check whether this is a full or partial reconciliation
|
||||
if st_line.import_transaction_id.payment_option=='with_writeoff':
|
||||
writeoff = abs(st_line.amount)-abs(amount_currency)
|
||||
line_amount = abs(amount_currency)
|
||||
else:
|
||||
writeoff = 0.0
|
||||
line_amount = abs(st_line.amount)
|
||||
|
||||
# Define the voucher
|
||||
voucher = {
|
||||
'journal_id': st_line.statement_id.journal_id.id,
|
||||
'partner_id': st_line.partner_id and st_line.partner_id.id or False,
|
||||
'company_id': st_line.company_id.id,
|
||||
'type':voucher_type,
|
||||
'company_id': st_line.company_id.id,
|
||||
'account_id': account_id,
|
||||
'amount': abs(st_line.amount),
|
||||
'writeoff_amount': writeoff,
|
||||
'payment_option': st_line.import_transaction_id.payment_option,
|
||||
'writeoff_acc_id': st_line.import_transaction_id.writeoff_account_id.id,
|
||||
'analytic_id': st_line.import_transaction_id.writeoff_analytic_id.id,
|
||||
'date': st_line.date,
|
||||
'date_due': st_line.date,
|
||||
'period_id': period_id,
|
||||
'payment_rate_currency_id':to_curr_id,
|
||||
}
|
||||
|
||||
# Define the voucher line
|
||||
vch_line = {
|
||||
#'voucher_id': v_id,
|
||||
'move_line_id': st_line.import_transaction_id.move_line_id.id,
|
||||
'reconcile': True,
|
||||
'amount': line_amount,
|
||||
'account_id': st_line.import_transaction_id.move_line_id.account_id.id,
|
||||
'type': st_line.import_transaction_id.move_line_id.credit and 'dr' or 'cr',
|
||||
}
|
||||
voucher['line_ids'] = [(0,0,vch_line)]
|
||||
v_id = self.pool.get('account.voucher').create(cr, uid, voucher, context=context)
|
||||
|
||||
return v_id
|
||||
|
||||
if not st_line.voucher_id.journal_id.entry_posted:
|
||||
move_pool.post(cr, uid, [st_line.voucher_id.move_id.id], context={})
|
||||
|
||||
def cancel(self, cr, uid, ids, context=None):
|
||||
if ids and isinstance(ids, (int, float)):
|
||||
@@ -1895,15 +1940,10 @@ class account_bank_statement_line(osv.osv):
|
||||
_("The bank statement that this transaction belongs to has "
|
||||
"already been confirmed"))
|
||||
|
||||
# Check if the transaction has a voucher
|
||||
if st_line.voucher_id:
|
||||
voucher_cancel_ids.append(st_line.voucher_id.id)
|
||||
if st_line.import_transaction_id:
|
||||
transaction_cancel_ids.append(st_line.import_transaction_id.id)
|
||||
else:
|
||||
if st_line.import_transaction_id:
|
||||
transaction_cancel_ids.append(st_line.import_transaction_id.id)
|
||||
if st_line.move_id:
|
||||
move_unlink_ids.append(st_line.move_id.id)
|
||||
else:
|
||||
if not st_line.move_id:
|
||||
raise osv.except_osv(
|
||||
_("Cannot cancel bank transaction"),
|
||||
_("Cannot cancel this bank transaction. The information "
|
||||
@@ -1911,16 +1951,9 @@ class account_bank_statement_line(osv.osv):
|
||||
"recorded"))
|
||||
set_draft_ids.append(st_line.id)
|
||||
|
||||
# Cancel and delete the vouchers
|
||||
voucher_pool.cancel_voucher(cr, uid, voucher_cancel_ids, context=context)
|
||||
voucher_pool.action_cancel_draft(cr, uid, voucher_cancel_ids, context=context)
|
||||
voucher_pool.unlink(cr, uid, voucher_cancel_ids, context=context)
|
||||
|
||||
# Perform actions
|
||||
import_transaction_obj.cancel(
|
||||
cr, uid, transaction_cancel_ids, context=context)
|
||||
account_move_obj.button_cancel(cr, uid, move_unlink_ids, context)
|
||||
account_move_obj.unlink(cr, uid, move_unlink_ids, context)
|
||||
self.write(
|
||||
cr, uid, set_draft_ids, {'state': 'draft'}, context=context)
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user