If you want to return the writeoff move.line which is to be reconciled follow the following code .
return writeoff_move.line_ids.filtered(lambda r: r.account_id == self[0].account_id)
@api.multi
def remove_move_reconcile(self):
""" Undo a reconciliation """
if not self:
return True
rec_move_ids = self.env['account.partial.reconcile']
for account_move_line in self:
rec_move_ids += account_move_line.matched_debit_ids
rec_move_ids += account_move_line.matched_credit_ids
return rec_move_ids.unlink()
@api.model
def create(self, vals, apply_taxes=True):
""" :param apply_taxes: set to False if you don't want vals['tax_ids'] to result in the creation of move lines for taxes and eventual
adjustment of the line amount (in case of a tax included in price). This is useful for use cases where you don't want to
apply taxes in the default fashion (eg. taxes). You can also pass 'dont_create_taxes' in context.
:context's key `check_move_validity`: check data consistency after move line creation. Eg. set to false to disable verification that the move
debit-credit == 0 while creating the move lines composing the move.
"""
AccountObj = self.env['account.account']
MoveObj = self.env['account.move']
context = dict(self._context or {})
amount = vals.get('debit', 0.0) - vals.get('credit', 0.0)
if vals.get('move_id', False):
move = MoveObj.browse(vals['move_id'])
if move.date and not vals.get('date'):
vals['date'] = move.date
if ('account_id' in vals) and AccountObj.browse(vals['account_id']).deprecated:
raise UserError(_('You cannot use deprecated account.'))
if 'journal_id' in vals and vals['journal_id']:
context['journal_id'] = vals['journal_id']
if 'date' in vals and vals['date']:
context['date'] = vals['date']
if ('journal_id' not in context) and ('move_id' in vals) and vals['move_id']:
m = MoveObj.browse(vals['move_id'])
context['journal_id'] = m.journal_id.id
context['date'] = m.date
#we need to treat the case where a value is given in the context for period_id as a string
if not context.get('journal_id', False) and context.get('search_default_journal_id', False):
context['journal_id'] = context.get('search_default_journal_id')
if 'date' not in context:
context['date'] = fields.Date.context_today(self)
move_id = vals.get('move_id', False)
journal = self.env['account.journal'].browse(context['journal_id'])
vals['journal_id'] = vals.get('journal_id') or context.get('journal_id')
vals['date'] = vals.get('date') or context.get('date')
vals['date_maturity'] = vals.get('date_maturity') if vals.get('date_maturity') else vals['date']
if not move_id:
if not vals.get('move_id', False):
if journal.sequence_id:
#name = self.pool.get('ir.sequence').next_by_id(cr, uid, journal.sequence_id.id)
v = {
'date': vals.get('date', time.strftime('%Y-%m-%d')),
'journal_id': context['journal_id']
}
if vals.get('ref', ''):
v.update({'ref': vals['ref']})
move_id = MoveObj.with_context(context).create(v)
vals['move_id'] = move_id.id
else:
raise UserError(_('Cannot create an automatic sequence for this piece.\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.'))
ok = not (journal.type_control_ids or journal.account_control_ids)
if ('account_id' in vals):
account = AccountObj.browse(vals['account_id'])
if journal.type_control_ids:
type = account.user_type_id
for t in journal.type_control_ids:
if type.code == t.code:
ok = True
break
if journal.account_control_ids and not ok:
for a in journal.account_control_ids:
if a.id == vals['account_id']:
ok = True
break
# Automatically convert in the account's secondary currency if there is one and
# the provided values were not already multi-currency
if account.currency_id and 'amount_currency' not in vals and account.currency_id.id != account.company_id.currency_id.id:
vals['currency_id'] = account.currency_id.id
ctx = {}
if 'date' in vals:
ctx['date'] = vals['date']
vals['amount_currency'] = account.company_id.currency_id.with_context(ctx).compute(amount, account.currency_id)
if not ok:
raise UserError(_('You cannot use this general account in this journal, check the tab \'Entry Controls\' on the related journal.'))
# Create tax lines
tax_lines_vals = []
if apply_taxes and not context.get('dont_create_taxes') and vals.get('tax_ids'):
# Get ids from triplets : https://www.odoo.com/documentation/master/reference/orm.html#openerp.models.Model.write
tax_ids = [tax['id'] for tax in self.resolve_2many_commands('tax_ids', vals['tax_ids']) if tax.get('id')]
# Since create() receives ids instead of recordset, let's just use the old-api bridge
taxes = self.env['account.tax'].browse(tax_ids)
currency = self.env['res.currency'].browse(vals.get('currency_id'))
res = taxes.compute_all(amount,
currency, 1, vals.get('product_id'), vals.get('partner_id'))
# Adjust line amount if any tax is price_include
if abs(res['total_excluded']) < abs(amount):
if vals['debit'] != 0.0: vals['debit'] = res['total_excluded']
if vals['credit'] != 0.0: vals['credit'] = -res['total_excluded']
if vals.get('amount_currency'):
vals['amount_currency'] = self.env['res.currency'].browse(vals['currency_id']).round(vals['amount_currency'] * (amount / res['total_excluded']))
# Create tax lines
for tax_vals in res['taxes']:
account_id = (amount > 0 and tax_vals['account_id'] or tax_vals['refund_account_id'])
if not account_id: account_id = vals['account_id']
tax_lines_vals.append({
'account_id': account_id,
'name': vals['name'] + ' ' + tax_vals['name'],
'tax_line_id': tax_vals['id'],
'move_id': vals['move_id'],
'date': vals['date'],
'partner_id': vals.get('partner_id'),
'ref': vals.get('ref'),
'statement_id': vals.get('statement_id'),
'debit': tax_vals['amount'] > 0 and tax_vals['amount'] or 0.0,
'credit': tax_vals['amount'] < 0 and -tax_vals['amount'] or 0.0,
})
new_line = super(AccountMoveLine, self).create(vals)
for tax_line_vals in tax_lines_vals:
# TODO: remove .with_context(context) once this context nonsense is solved
self.with_context(context).create(tax_line_vals)
if self._context.get('check_move_validity', True):
move = MoveObj.browse(vals['move_id'])
move.with_context(context)._post_validate()
return new_line
@api.multi
def unlink(self):
self._update_check()
move_ids = set()
for line in self:
if line.move_id.id not in move_ids:
move_ids.add(line.move_id.id)
result = super(AccountMoveLine, self).unlink()
if self._context.get('check_move_validity', True) and move_ids:
self.env['account.move'].browse(list(move_ids))._post_validate()
return result
@api.multi
def write(self, vals):
if vals.get('tax_line_id') or vals.get('tax_ids'):
raise UserError(_('You cannot change the tax, you should remove and recreate lines.'))
if ('account_id' in vals) and self.env['account.account'].browse(vals['account_id']).deprecated:
raise UserError(_('You cannot use deprecated account.'))
if any(key in vals for key in ('account_id', 'journal_id', 'date', 'move_id', 'debit', 'credit', 'amount_currency', 'currency_id')):
self._update_check()
#when we set the expected payment date, log a note on the invoice_id related (if any)
if vals.get('expected_pay_date') and self.invoice_id:
msg = _('New expected payment date: ') + vals['expected_pay_date'] + '.\n' + vals.get('internal_note', '')
self.invoice_id.message_post(body=msg) #TODO: check it is an internal note (not a regular email)!
#when making a reconciliation on an existing liquidity journal item, mark the payment as reconciled
if 'statement_id' in vals and self.payment_id:
# In case of an internal transfer, there are 2 liquidity move lines to match with a bank statement
if all(line.statement_id for line in self.payment_id.move_line_ids.filtered(lambda r: r.id != self.id and r.account_id.internal_type=='liquidity')):
self.payment_id.state = 'reconciled'
result = super(AccountMoveLine, self).write(vals)
if self._context.get('check_move_validity', True):
move_ids = set()
for line in self:
if line.move_id.id not in move_ids:
move_ids.add(line.move_id.id)
self.env['account.move'].browse(list(move_ids))._post_validate()
return result
0 Comment(s)