[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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user