[IMP] account : remove internal transfers

Needed for payments refactor

Task : 2199740

closes odoo/odoo#45812

Related: odoo/upgrade#943
Related: odoo/enterprise#8595
Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
This commit is contained in:
jbw
2020-03-24 14:34:12 +00:00
parent b42abefd1e
commit a30cfee04e
6 changed files with 73 additions and 295 deletions
@@ -493,6 +493,8 @@ class account_journal(models.Model):
action_ref = 'account.action_account_payments'
[action] = self.env.ref(action_ref).read()
action['context'] = dict(ast.literal_eval(action.get('context')), default_journal_id=self.id, search_default_journal_id=self.id)
if payment_type == 'transfer':
action['context']['default_partner_id'] = self.company_id.partner_id.id
if mode == 'form':
action['views'] = [[False, 'form']]
return action
+32 -101
View File
@@ -38,8 +38,6 @@ class account_payment(models.Model):
# Money flows from the journal_id's default_debit_account_id or default_credit_account_id to the destination_account_id
destination_account_id = fields.Many2one('account.account', compute='_compute_destination_account_id', readonly=True)
# For money transfer, money goes from journal_id to a transfer account, then from the transfer account to destination_journal_id
destination_journal_id = fields.Many2one('account.journal', string='Transfer To', domain="[('type', 'in', ('bank', 'cash')), ('company_id', '=', company_id)]", readonly=True, states={'draft': [('readonly', False)]})
invoice_ids = fields.Many2many('account.move', 'account_invoice_payment_rel', 'payment_id', 'invoice_id', string="Invoices", copy=False, readonly=True,
help="""Technical field containing the invoice for which the payment has been generated.
@@ -53,7 +51,7 @@ class account_payment(models.Model):
move_reconciled = fields.Boolean(compute="_get_move_reconciled", readonly=True)
state = fields.Selection([('draft', 'Draft'), ('posted', 'Validated'), ('sent', 'Sent'), ('reconciled', 'Reconciled'), ('cancelled', 'Cancelled'), ('invoicing_legacy', 'Invoicing App Legacy')], readonly=True, default='draft', copy=False, string="Status", tracking=True)
payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money'), ('transfer', 'Internal Transfer')], string='Payment Type', required=True, readonly=True, states={'draft': [('readonly', False)]})
payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money')], string='Payment Type', required=True, readonly=True, states={'draft': [('readonly', False)]})
_payment_methods = fields.Many2many('account.payment.method', compute='_compute_payment_methods')
payment_method_id = fields.Many2one('account.payment.method', string='Payment Method', required=True, readonly=True, states={'draft': [('readonly', False)]},
domain="""[
@@ -70,7 +68,7 @@ class account_payment(models.Model):
partner_type = fields.Selection([('customer', 'Customer'), ('supplier', 'Vendor')], tracking=True, readonly=True, states={'draft': [('readonly', False)]})
partner_id = fields.Many2one('res.partner', string='Partner', tracking=True, readonly=True, states={'draft': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
is_internal_transfer = fields.Boolean(compute="_compute_is_internal_transfer", store=True)
amount = fields.Monetary(string='Amount', required=True, readonly=True, states={'draft': [('readonly', False)]}, tracking=True)
currency_id = fields.Many2one('res.currency', string='Currency', required=True, readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.company.currency_id)
payment_date = fields.Date(string='Date', default=fields.Date.context_today, required=True, readonly=True, states={'draft': [('readonly', False)]}, copy=False, tracking=True)
@@ -133,6 +131,11 @@ class account_payment(models.Model):
})
return rec
@api.depends('partner_id', 'journal_id')
def _compute_is_internal_transfer(self):
for payment in self:
payment.is_internal_transfer = payment.partner_id == payment.journal_id.company_id.partner_id
@api.depends('amount', 'currency_id', 'payment_type', 'company_id', 'invoice_ids.company_id', )
def _compute_suitable_journal_ids(self):
for p in self:
@@ -245,10 +248,8 @@ class account_payment(models.Model):
# Set default partner type for the payment type
if self.payment_type == 'inbound':
self.partner_type = 'customer'
elif self.payment_type == 'outbound':
else: # -> self.payment_type == 'outbound'
self.partner_type = 'supplier'
elif self.payment_type not in ('inbound', 'outbound'):
self.partner_type = False
self._onchange_journal()
if self.currency_id.is_zero(self.amount) and self.has_invoices:
self.payment_difference_handling = 'reconcile'
@@ -331,10 +332,6 @@ class account_payment(models.Model):
def name_get(self):
return [(payment.id, payment.name or _('Draft Payment')) for payment in self]
@api.model
def _get_move_name_transfer_separator(self):
return '§§'
@api.depends('move_line_ids.reconciled')
def _get_move_reconciled(self):
for payment in self:
@@ -345,7 +342,7 @@ class account_payment(models.Model):
break
payment.move_reconciled = rec
@api.depends('invoice_ids', 'payment_type', 'partner_type', 'partner_id')
@api.depends('invoice_ids', 'payment_type', 'partner_type', 'partner_id', 'is_internal_transfer')
def _compute_destination_account_id(self):
for payment in self:
payment = payment.with_company(payment.company_id)
@@ -353,7 +350,7 @@ class account_payment(models.Model):
payment.destination_account_id = payment.invoice_ids[0].mapped(
'line_ids.account_id').filtered(
lambda account: account.user_type_id.type in ('receivable', 'payable'))[0]
elif payment.payment_type == 'transfer':
elif payment.is_internal_transfer:
if not payment.company_id.transfer_account_id.id:
raise UserError(_('There is no Transfer Account defined in the accounting settings. Please define one to be able to confirm this transfer.'))
payment.destination_account_id = payment.company_id.transfer_account_id.id
@@ -439,7 +436,7 @@ class account_payment(models.Model):
''' Prepare the creation of journal entries (account.move) by creating a list of python dictionary to be passed
to the 'create' method.
Example 1: outbound with write-off:
Example : outbound with write-off:
Account | Debit | Credit
---------------------------------------------------------
@@ -447,25 +444,15 @@ class account_payment(models.Model):
RECEIVABLE | | 1000.0
WRITE-OFF ACCOUNT | 100.0 |
Example 2: internal transfer from BANK to CASH:
Account | Debit | Credit
---------------------------------------------------------
BANK | | 1000.0
TRANSFER | 1000.0 |
CASH | 1000.0 |
TRANSFER | | 1000.0
:return: A list of Python dictionary to be passed to env['account.move'].create.
'''
all_move_vals = []
for payment in self:
company_currency = payment.company_id.currency_id
move_names = payment.move_name.split(payment._get_move_name_transfer_separator()) if payment.move_name else None
# Compute amounts.
write_off_amount = payment.payment_difference_handling == 'reconcile' and -payment.payment_difference or 0.0
if payment.payment_type in ('outbound', 'transfer'):
if payment.payment_type == 'outbound':
counterpart_amount = payment.amount
liquidity_line_account = payment.journal_id.default_debit_account_id
else:
@@ -502,7 +489,7 @@ class account_payment(models.Model):
# Compute 'name' to be used in receivable/payable line.
rec_pay_line_name = ''
if payment.payment_type == 'transfer':
if payment.is_internal_transfer:
rec_pay_line_name = payment.name
else:
if payment.partner_type == 'customer':
@@ -519,8 +506,11 @@ class account_payment(models.Model):
rec_pay_line_name += ': %s' % ', '.join(payment.invoice_ids.mapped('name'))
# Compute 'name' to be used in liquidity line.
if payment.payment_type == 'transfer':
liquidity_line_name = _('Transfer to %s') % payment.destination_journal_id.name
if payment.is_internal_transfer:
if payment.payment_type == 'inbound':
liquidity_line_name = _('Transfer to %s') % payment.journal_id.name
elif payment.payment_type == 'outbound':
liquidity_line_name = _('Transfer from %s') % payment.journal_id.name
else:
liquidity_line_name = payment.name
@@ -573,62 +563,11 @@ class account_payment(models.Model):
'payment_id': payment.id,
}))
if move_names:
move_vals['name'] = move_names[0]
if payment.move_name:
move_vals['name'] = payment.move_name
all_move_vals.append(move_vals)
# ==== 'transfer' ====
if payment.payment_type == 'transfer':
journal = payment.destination_journal_id
# Manage custom currency on journal for liquidity line.
if journal.currency_id and payment.currency_id != journal.currency_id:
# Custom currency on journal.
liquidity_line_currency_id = journal.currency_id.id
transfer_amount = company_currency._convert(balance, journal.currency_id, payment.company_id, payment.payment_date)
else:
# Use the payment currency.
liquidity_line_currency_id = currency_id
transfer_amount = counterpart_amount
transfer_move_vals = {
'date': payment.payment_date,
'ref': payment.communication,
'partner_id': payment.partner_id.id,
'journal_id': payment.destination_journal_id.id,
'line_ids': [
# Transfer debit line.
(0, 0, {
'name': payment.name,
'amount_currency': -counterpart_amount if currency_id else 0.0,
'currency_id': currency_id,
'debit': balance < 0.0 and -balance or 0.0,
'credit': balance > 0.0 and balance or 0.0,
'date_maturity': payment.payment_date,
'partner_id': payment.partner_id.commercial_partner_id.id,
'account_id': payment.company_id.transfer_account_id.id,
'payment_id': payment.id,
}),
# Liquidity credit line.
(0, 0, {
'name': _('Transfer from %s') % payment.journal_id.name,
'amount_currency': transfer_amount if liquidity_line_currency_id else 0.0,
'currency_id': liquidity_line_currency_id,
'debit': balance > 0.0 and balance or 0.0,
'credit': balance < 0.0 and -balance or 0.0,
'date_maturity': payment.payment_date,
'partner_id': payment.partner_id.commercial_partner_id.id,
'account_id': payment.destination_journal_id.default_credit_account_id.id,
'payment_id': payment.id,
}),
],
}
if move_names and len(move_names) == 2:
transfer_move_vals['name'] = move_names[1]
all_move_vals.append(transfer_move_vals)
return all_move_vals
def post(self):
@@ -649,41 +588,33 @@ class account_payment(models.Model):
# keep the name in case of a payment reset to draft
if not rec.name:
# Use the right sequence to set the name
if rec.payment_type == 'transfer':
if rec.is_internal_transfer:
sequence_code = 'account.payment.transfer'
else:
if rec.partner_type == 'customer':
if rec.payment_type == 'inbound':
sequence_code = 'account.payment.customer.invoice'
if rec.payment_type == 'outbound':
elif rec.payment_type == 'outbound':
sequence_code = 'account.payment.customer.refund'
if rec.partner_type == 'supplier':
elif rec.partner_type == 'supplier':
if rec.payment_type == 'inbound':
sequence_code = 'account.payment.supplier.refund'
if rec.payment_type == 'outbound':
elif rec.payment_type == 'outbound':
sequence_code = 'account.payment.supplier.invoice'
rec.name = self.env['ir.sequence'].next_by_code(sequence_code, sequence_date=rec.payment_date)
if not rec.name and rec.payment_type != 'transfer':
if not rec.name and not rec.is_internal_transfer:
raise UserError(_("You have to define a sequence for %s in your company.") % (sequence_code,))
moves = AccountMove.create(rec._prepare_payment_moves())
moves.filtered(lambda move: move.journal_id.post_at != 'bank_rec').post()
move = AccountMove.create(rec._prepare_payment_moves())
if move.journal_id.post_at != 'bank_rec':
move.post()
# Update the state / move before performing any reconciliation.
move_name = self._get_move_name_transfer_separator().join(moves.mapped('name'))
rec.write({'state': 'posted', 'move_name': move_name})
rec.write({'state': 'posted', 'move_name': move.name})
if rec.payment_type in ('inbound', 'outbound'):
# ==== 'inbound' / 'outbound' ====
if rec.invoice_ids:
(moves[0] + rec.invoice_ids).line_ids \
.filtered(lambda line: not line.reconciled and line.account_id == rec.destination_account_id)\
.reconcile()
elif rec.payment_type == 'transfer':
# ==== 'transfer' ====
moves.mapped('line_ids')\
.filtered(lambda line: line.account_id == rec.company_id.transfer_account_id)\
if rec.invoice_ids:
(move + rec.invoice_ids).line_ids \
.filtered(lambda line: not line.reconciled and line.account_id == rec.destination_account_id)\
.reconcile()
return True
+30 -100
View File
@@ -15,24 +15,19 @@ class TestAccountMovePayment(AccountTestInvoicingCommon):
cls.bank_journal = cls.company_data['default_journal_bank']
cls.bank_journal.default_credit_account_id = cls.bank_journal.default_debit_account_id.copy()
cls.cash_journal = cls.company_data['default_journal_cash']
cls.cash_journal.default_credit_account_id = cls.cash_journal.default_debit_account_id.copy()
cls.inbound_payment = cls._init_payment(cls, 'inbound', partner_type='customer')
cls.outbound_payment = cls._init_payment(cls, 'outbound', partner_type='supplier')
cls.transfer_payment = cls._init_payment(cls, 'transfer')
cls.inbound_payment = cls._init_payment(cls, 'inbound', cls.partner_a, partner_type='customer')
cls.outbound_payment = cls._init_payment(cls, 'outbound', cls.partner_a, partner_type='supplier')
cls.inbound_internal_transfer = cls._init_payment(cls, 'inbound', cls.company_data['company'].partner_id)
cls.outbound_internal_transfer = cls._init_payment(cls, 'outbound', cls.company_data['company'].partner_id)
@staticmethod
def _init_payment(cls, payment_type, partner_type=None):
def _init_payment(cls, payment_type, partner_id, partner_type=None):
payment_form = Form(cls.env['account.payment'])
payment_form.journal_id = cls.bank_journal
payment_form.payment_date = fields.Date.from_string('2019-01-01')
payment_form.amount = 100
if payment_type == 'transfer':
payment_form.destination_journal_id = cls.cash_journal
else:
payment_form.partner_type = partner_type
payment_form.partner_id = cls.partner_a
payment_form.partner_type = partner_type
payment_form.partner_id = partner_id
payment_form.payment_type = payment_type
return payment_form.save()
@@ -177,116 +172,51 @@ class TestAccountMovePayment(AccountTestInvoicingCommon):
expected_payable_line,
])
def test_transfer_payment_move_1(self):
''' Check created account.move for an account.payment having the 'transfer' type. '''
def test_inbound_transfer_payment_1(self):
liquidity_bank_account = self.bank_journal.default_debit_account_id
liquidity_cash_account = self.cash_journal.default_credit_account_id
cash_transfer_line = {
self.inbound_internal_transfer.post()
transfer_line = {
'account_id': self.company_data['company'].transfer_account_id.id,
'partner_id': False,
'partner_id': self.company_data['company'].partner_id.id,
'currency_id': False,
'amount_currency': 0.0,
'debit': 0.0,
'credit': 100.0,
}
bank_transfer_line = {
'account_id': self.company_data['company'].transfer_account_id.id,
'partner_id': False,
liquidity_bank_line = {
'account_id': self.bank_journal.default_credit_account_id.id,
'partner_id': self.company_data['company'].partner_id.id,
'currency_id': False,
'amount_currency': 0.0,
'debit': 100.0,
'credit': 0.0,
}
liquidity_cash_line = {
'account_id': liquidity_cash_account.id,
'partner_id': False,
self.assertPaymentValues(self.inbound_internal_transfer, [
transfer_line,
liquidity_bank_line,
])
self.assertTrue(self.inbound_internal_transfer.is_internal_transfer)
def test_outbound_transfer_payment_1(self):
self.outbound_internal_transfer.post()
transfer_line = {
'account_id': self.company_data['company'].transfer_account_id.id,
'partner_id': self.company_data['company'].partner_id.id,
'currency_id': False,
'amount_currency': 0.0,
'debit': 100.0,
'credit': 0.0,
}
liquidity_bank_line = {
'account_id': liquidity_bank_account.id,
'partner_id': False,
'account_id': self.bank_journal.default_debit_account_id.id,
'partner_id': self.company_data['company'].partner_id.id,
'currency_id': False,
'amount_currency': 0.0,
'debit': 0.0,
'credit': 100.0,
}
# Single currency.
self.transfer_payment.post()
self.assertPaymentValues(self.transfer_payment, [
cash_transfer_line,
bank_transfer_line,
liquidity_cash_line,
self.assertPaymentValues(self.outbound_internal_transfer, [
transfer_line,
liquidity_bank_line,
])
# Multi currencies: Foreign currency on payment.
self.transfer_payment.action_draft()
self.transfer_payment.currency_id = self.currency_data['currency']
self.transfer_payment.post()
self.assertPaymentValues(self.transfer_payment, [
{
**cash_transfer_line,
'currency_id': self.currency_data['currency'].id,
'amount_currency': -100.0,
'credit': 50.0,
},
{
**bank_transfer_line,
'currency_id': self.currency_data['currency'].id,
'amount_currency': 100.0,
'debit': 50.0,
},
{
**liquidity_cash_line,
'currency_id': self.currency_data['currency'].id,
'amount_currency': 100.0,
'debit': 50.0,
},
{
**liquidity_bank_line,
'currency_id': self.currency_data['currency'].id,
'amount_currency': -100.0,
'credit': 50.0,
},
])
self.transfer_payment.currency_id = self.company_data['currency']
# Multi currencies: Foreign currency on journal.
self.transfer_payment.action_draft()
self.transfer_payment.journal_id.currency_id = self.currency_data['currency']
self.transfer_payment.destination_journal_id.currency_id = self.currency_data['currency']
self.transfer_payment.post()
self.assertPaymentValues(self.transfer_payment, [
{
**cash_transfer_line,
'credit': 100.0,
},
{
**bank_transfer_line,
'debit': 100.0,
},
{
**liquidity_cash_line,
'currency_id': self.currency_data['currency'].id,
'amount_currency': 200.0,
'debit': 100.0,
},
{
**liquidity_bank_line,
'currency_id': self.currency_data['currency'].id,
'amount_currency': -200.0,
'credit': 100.0,
},
])
self.assertTrue(self.outbound_internal_transfer.is_internal_transfer)
+3 -86
View File
@@ -142,20 +142,19 @@ class TestPayment(AccountTestCommon):
def test_internal_transfer_journal_usd_journal_eur(self):
""" Create a transfer from a EUR journal to a USD journal """
payment = self.payment_model.create({
'partner_id': self.company.partner_id.id,
'payment_date': time.strftime('%Y') + '-07-15',
'payment_type': 'transfer',
'payment_type': 'outbound',
'partner_type': 'customer',
'amount': 50,
'currency_id': self.currency_usd_id,
'journal_id': self.bank_journal_usd.id,
'destination_journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_out.id,
})
payment.post()
self.assertRecordValues(payment.move_line_ids, [
{'account_id': self.transfer_account.id, 'debit': 32.70, 'credit': 0.0, 'amount_currency': 50, 'currency_id': self.currency_usd_id},
{'account_id': self.account_usd.id, 'debit': 0.0, 'credit': 32.70, 'amount_currency': -50, 'currency_id': self.currency_usd_id},
{'account_id': self.transfer_account.id, 'debit': 0.0, 'credit': 32.70, 'amount_currency': -50, 'currency_id': self.currency_usd_id},
{'account_id': self.account_eur.id, 'debit': 32.70, 'credit': 0.0, 'amount_currency': 50, 'currency_id': self.currency_usd_id},
])
def test_payment_chf_journal_usd(self):
@@ -487,88 +486,6 @@ class TestPayment(AccountTestCommon):
self.assertEqual(len(payment.move_line_ids.mapped('move_id')), 1)
self.assertEqual(name, payment.move_line_ids.mapped('move_id').name)
def test_payment_transfer_draft_keep_names(self):
payment = self.payment_model.create({
'payment_type': 'transfer',
'payment_method_id': self.payment_method_manual_out.id,
'amount': 90,
'payment_date': time.strftime('%Y') + '-07-15',
'journal_id': self.bank_journal_euro.id,
'destination_journal_id': self.cash_journal_euro.id,
})
payment.post()
self.assertEqual(len(payment.move_line_ids.mapped('move_id')), 2)
all_moves = payment.move_line_ids.mapped('move_id')
move = all_moves.filtered(lambda m: m.journal_id == self.bank_journal_euro)
transfer_move = all_moves - move
self.assertEqual(transfer_move.journal_id, self.cash_journal_euro)
name = move.name
transfer_name = transfer_move.name
self.assertTrue(name)
self.assertTrue(transfer_name)
self.assertNotEqual(name, transfer_name)
reconciled_lines = payment.move_line_ids.filtered(lambda l: l.reconciled)
self.assertEqual(len(reconciled_lines), 2)
self.assertEqual(reconciled_lines.mapped('move_id'), all_moves)
reconciled_lines.remove_move_reconcile()
payment.action_draft()
self.assertFalse(payment.move_line_ids.mapped('move_id'))
payment.post()
self.assertEqual(len(payment.move_line_ids.mapped('move_id')), 2)
all_moves = payment.move_line_ids.mapped('move_id')
move = all_moves.filtered(lambda m: m.journal_id == self.bank_journal_euro)
transfer_move = all_moves - move
self.assertEqual(transfer_move.journal_id, self.cash_journal_euro)
self.assertEqual(name, move.name)
self.assertEqual(transfer_name, transfer_move.name)
def test_payment_draft_to_transfer(self):
payment = self.payment_model.create({
'payment_type': 'inbound',
'payment_method_id': self.payment_method_manual_in.id,
'partner_type': 'customer',
'partner_id': self.partner_agrolait.id,
'amount': 90,
'payment_date': time.strftime('%Y') + '-07-15',
'payment_difference_handling': 'reconcile',
'journal_id': self.bank_journal_euro.id,
})
payment.post()
self.assertEqual(len(payment.move_line_ids.mapped('move_id')), 1)
name = payment.move_line_ids.mapped('move_id').name
self.assertTrue(name)
payment.action_draft()
self.assertFalse(payment.move_line_ids.mapped('move_id'))
payment.write({
'payment_type': 'transfer',
'payment_method_id': self.payment_method_manual_out.id,
'partner_id': False,
'destination_journal_id': self.cash_journal_euro.id,
})
payment.post()
self.assertEqual(len(payment.move_line_ids.mapped('move_id')), 2)
all_moves = payment.move_line_ids.mapped('move_id')
move = all_moves.filtered(lambda m: m.journal_id == self.bank_journal_euro)
transfer_move = all_moves - move
self.assertEqual(transfer_move.journal_id, self.cash_journal_euro)
self.assertEqual(name, move.name)
self.assertTrue(transfer_move.name)
self.assertNotEqual(name, transfer_move.name)
def test_partial_payment_inv_foreign_payment_domestic(self):
"""
Invoice of 1000$ (foreign $) at 01/01 with foreign exchange rate of 0.50000
@@ -534,7 +534,6 @@ class TestReconciliationExec(TestAccountReconciliationCommon):
'payment_date': time.strftime('%Y') + '-' + '07' + '-01',
'partner_id': self.partner_agrolait_id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
'destination_journal_id': dest_journal_id.id,
'partner_type': 'supplier'})
# One that will complete the payment of a, the rest goes to b
@@ -546,7 +545,6 @@ class TestReconciliationExec(TestAccountReconciliationCommon):
'payment_date': time.strftime('%Y') + '-' + '08' + '-01',
'partner_id': self.partner_agrolait_id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
'destination_journal_id': dest_journal_id.id,
'partner_type': 'supplier'})
# The last one will complete the payment of b
@@ -558,7 +556,6 @@ class TestReconciliationExec(TestAccountReconciliationCommon):
'payment_date': time.strftime('%Y') + '-' + '09' + '-01',
'partner_id': self.partner_agrolait_id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
'destination_journal_id': dest_journal_id.id,
'partner_type': 'supplier'})
payment_a.post()
@@ -85,10 +85,11 @@
filter_domain="['|', '|', ('name', 'ilike', self), ('partner_id', 'ilike', self), ('communication', 'ilike', self)]"/>
<field name="partner_id" string="Customer/Vendor"/>
<field name="journal_id"/>
<field name="is_internal_transfer"/>
<separator/>
<filter string="Customer Payments" name="inbound_filter" domain="[('partner_type', '=', 'customer')]"/>
<filter string="Vendor Payments" name="outbound_filter" domain="[('partner_type', '=', 'supplier')]"/>
<filter string="Transfers" name="transfers_filter" domain="[('payment_type', '=', 'transfer')]"/>
<filter string="Transfers" name="transfers_filter" domain="[('is_internal_transfer', '=', True)]"/>
<separator/>
<filter string="Draft" name="state_draft" domain="[('state', '=', 'draft')]"/>
<filter string="Posted" name="state_posted" domain="[('state', '=', 'posted')]"/>
@@ -159,17 +160,17 @@
<group>
<field name="invoice_ids" invisible="1"/>
<field name="is_internal_transfer" invisible="1"/>
<group name="partner_group" invisible="context.get('active_model') == 'account.move'">
<field name="payment_type" widget="radio"/>
<field name="partner_type" widget="selection" attrs="{'required': [('state', '=', 'draft'), ('payment_type', 'in', ('inbound', 'outbound'))], 'invisible': [('payment_type', 'not in', ('inbound', 'outbound'))]}"/>
<field name="partner_id" attrs="{'required': [('state', '=', 'draft'), ('payment_type', 'in', ('inbound', 'outbound'))], 'invisible': [('payment_type', 'not in', ('inbound', 'outbound'))]}" context="{'default_is_company': True}"/>
<field name="partner_type" widget="selection" attrs="{'required': [('state', '=', 'draft')], 'invisible': [('is_internal_transfer', '=', True)]}"/>
<field name="partner_id" attrs="{'required': [('state', '=', 'draft')]}" context="{'default_is_company': True}"/>
<field name="company_id" groups="base.group_multi_company" required="1"/>
</group>
<group>
<field name="amount" invisible="1"/>
<field name="_suitable_journal_ids" invisible="1"/>
<field name="journal_id" widget="selection" attrs="{'invisible': [('amount', '=', 0), ('state', '!=', 'draft')]}"/>
<field name="destination_journal_id" widget="selection" attrs="{'required': [('payment_type', '=', 'transfer')], 'invisible': [('payment_type', '!=', 'transfer')]}"/>
<field name="hide_payment_method" invisible="1"/>
<field name="_payment_methods" invisible="1"/>
<field name="payment_method_id" widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
@@ -294,7 +295,7 @@
<field name="name">Internal Transfers</field>
<field name="res_model">account.payment</field>
<field name="view_mode">tree,kanban,form,graph</field>
<field name="context">{'default_payment_type': 'transfer', 'search_default_transfers_filter': 1}</field>
<field name="context">{'default_payment_type': 'outbound', 'search_default_transfers_filter': 1}</field>
<field name="domain">[]</field>
<field name="view_id" ref="view_account_supplier_payment_tree"/>
<field name="help" type="html">