[IMP] account: visible but not required bank account on payment
When making a manual payment with account_sepa we want to allow people to add a bank account as it might display the European QR code for banking app, but this should stay optional. So we made sure that the conditions making the field visible and required weren't the same. part of task #1918423 closes odoo/odoo#32198 Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
This commit is contained in:
@@ -1034,7 +1034,7 @@ class AccountInvoice(models.Model):
|
||||
|
||||
@api.multi
|
||||
def action_register_payment(self):
|
||||
return self.env['account.payment'].with_context(active_ids=self.ids, active_model='account.invoice').action_register_payment()
|
||||
return self.env['account.payment'].with_context(active_ids=self.ids, active_model='account.invoice', active_id=self.id).action_register_payment()
|
||||
|
||||
@api.multi
|
||||
def action_invoice_cancel(self):
|
||||
|
||||
@@ -91,6 +91,7 @@ class account_payment(models.Model):
|
||||
default='Write-Off')
|
||||
partner_bank_account_id = fields.Many2one('res.partner.bank', string="Recipient Bank Account", readonly=True, states={'draft': [('readonly', False)]})
|
||||
show_partner_bank_account = fields.Boolean(compute='_compute_show_partner_bank', help='Technical field used to know whether the field `partner_bank_account_id` needs to be displayed or not in the payments form views')
|
||||
require_partner_bank_account = fields.Boolean(compute='_compute_show_partner_bank', help='Technical field used to know whether the field `partner_bank_account_id` needs to be required or not in the payments form views')
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
@@ -130,12 +131,17 @@ class account_payment(models.Model):
|
||||
def _get_method_codes_using_bank_account(self):
|
||||
return []
|
||||
|
||||
@api.model
|
||||
def _get_method_codes_needing_bank_account(self):
|
||||
return []
|
||||
|
||||
@api.depends('payment_method_code')
|
||||
def _compute_show_partner_bank(self):
|
||||
""" Computes if the destination bank account must be displayed in the payment form view. By default, it
|
||||
won't be displayed but some modules might change that, depending on the payment type."""
|
||||
for payment in self:
|
||||
payment.show_partner_bank_account = payment.payment_method_code in self._get_method_codes_using_bank_account()
|
||||
payment.require_partner_bank_account = payment.payment_method_code in self._get_method_codes_needing_bank_account()
|
||||
|
||||
@api.multi
|
||||
@api.depends('payment_type', 'journal_id')
|
||||
@@ -208,14 +214,14 @@ class account_payment(models.Model):
|
||||
|
||||
@api.onchange('payment_type')
|
||||
def _onchange_payment_type(self):
|
||||
if not self.invoice_ids:
|
||||
if not self.invoice_ids and not self.partner_type:
|
||||
# Set default partner type for the payment type
|
||||
if self.payment_type == 'inbound':
|
||||
self.partner_type = 'customer'
|
||||
elif self.payment_type == 'outbound':
|
||||
self.partner_type = 'supplier'
|
||||
else:
|
||||
self.partner_type = False
|
||||
elif self.payment_type not in ('inbound', 'outbound'):
|
||||
self.partner_type = False
|
||||
# Set payment method domain
|
||||
res = self._onchange_journal()
|
||||
if not res.get('domain', {}):
|
||||
@@ -366,54 +372,11 @@ class account_payment(models.Model):
|
||||
record.move_line_ids.mapped('matched_credit_ids.credit_move_id.invoice_id'))
|
||||
record.has_invoices = bool(record.reconciled_invoice_ids)
|
||||
|
||||
<<<<<<< HEAD
|
||||
@api.onchange('partner_type')
|
||||
def _onchange_partner_type(self):
|
||||
self.ensure_one()
|
||||
# Set partner_id domain
|
||||
if self.partner_type:
|
||||
return {'domain': {'partner_id': [(self.partner_type, '=', True)]}}
|
||||
|
||||
@api.onchange('payment_type')
|
||||
def _onchange_payment_type(self):
|
||||
if not self.invoice_ids and not self.partner_type:
|
||||
# Set default partner type for the payment type
|
||||
if self.payment_type == 'inbound':
|
||||
self.partner_type = 'customer'
|
||||
elif self.payment_type == 'outbound':
|
||||
self.partner_type = 'supplier'
|
||||
elif self.payment_type not in ('inbound', 'outbound'):
|
||||
self.partner_type = False
|
||||
# Set payment method domain
|
||||
res = self._onchange_journal()
|
||||
if not res.get('domain', {}):
|
||||
res['domain'] = {}
|
||||
jrnl_filters = self._compute_journal_domain_and_types()
|
||||
journal_types = jrnl_filters['journal_types']
|
||||
journal_types.update(['bank', 'cash'])
|
||||
res['domain']['journal_id'] = jrnl_filters['domain'] + [('type', 'in', list(journal_types))]
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
rec = super(account_payment, self).default_get(fields)
|
||||
invoice_defaults = self.resolve_2many_commands('invoice_ids', rec.get('invoice_ids'))
|
||||
if invoice_defaults and len(invoice_defaults) == 1:
|
||||
invoice = invoice_defaults[0]
|
||||
rec['communication'] = invoice['reference'] or invoice['name'] or invoice['number']
|
||||
rec['currency_id'] = invoice['currency_id'][0]
|
||||
rec['payment_type'] = invoice['type'] in ('out_invoice', 'in_refund') and 'inbound' or 'outbound'
|
||||
rec['partner_type'] = MAP_INVOICE_TYPE_PARTNER_TYPE[invoice['type']]
|
||||
rec['partner_id'] = invoice['partner_id'][0]
|
||||
rec['amount'] = invoice['residual']
|
||||
return rec
|
||||
=======
|
||||
@api.multi
|
||||
def action_register_payment(self):
|
||||
active_ids = self.env.context.get('active_ids')
|
||||
if not active_ids:
|
||||
return ''
|
||||
>>>>>>> [REF] account: simplification of payments objects
|
||||
|
||||
return {
|
||||
'name': _('Register Payment'),
|
||||
@@ -421,7 +384,7 @@ class account_payment(models.Model):
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'view_id': len(active_ids) != 1 and self.env.ref('account.view_account_payment_form_multi').id or self.env.ref('account.view_account_payment_invoice_form').id,
|
||||
'context': {**self.env.context, **{'active_model': 'account.invoice', 'active_ids': active_ids}},
|
||||
'context': self.env.context,
|
||||
'target': 'new',
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
@@ -722,6 +685,11 @@ class payment_register(models.TransientModel):
|
||||
# Check all invoices are open
|
||||
if any(invoice.state != 'open' for invoice in invoices):
|
||||
raise UserError(_("You can only register payments for open invoices"))
|
||||
# Check all invoices are inbound or all invoices are outbound
|
||||
outbound_list = [invoice.type in ('in_invoice', 'out_refund') for invoice in invoices]
|
||||
first_outbound = invoices[0].type in ('in_invoice', 'out_refund')
|
||||
if any(x != first_outbound for x in outbound_list):
|
||||
raise UserError(_("You can only register at the same time for payment that are all inbound or all outbound"))
|
||||
if 'invoice_ids' not in rec:
|
||||
rec['invoice_ids'] = [(6, 0, invoices.ids)]
|
||||
if 'journal_id' not in rec:
|
||||
@@ -734,18 +702,18 @@ class payment_register(models.TransientModel):
|
||||
rec['payment_method_id'] = self.env['account.payment.method'].search(domain, limit=1).id
|
||||
return rec
|
||||
|
||||
@api.model
|
||||
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
|
||||
res = super(payment_register, self).fields_view_get(view_id, view_type, toolbar, submenu)
|
||||
if 'active_domain' not in self.env.context:
|
||||
return res
|
||||
@api.onchange('journal_id', 'invoice_ids')
|
||||
def _onchange_journal(self):
|
||||
active_ids = self._context.get('active_ids')
|
||||
invoices = self.env['account.invoice'].browse(active_ids)
|
||||
if self.journal_id and invoices:
|
||||
if invoices[0].type in ('out_invoice', 'in_refund'):
|
||||
domain = [('payment_type', '=', 'inbound'), ('id', 'in', self.journal_id.inbound_payment_method_ids.ids)]
|
||||
else:
|
||||
domain = [('payment_type', '=', 'outbound'), ('id', 'in', self.journal_id.outbound_payment_method_ids.ids)]
|
||||
|
||||
type = [dom[2] for dom in self.env.context['active_domain'] if dom[0] == 'type'][0]
|
||||
if type in ('out_invoice', 'in_refund'):
|
||||
res['fields']['payment_method_id']['domain'] = [('payment_type', '=', 'inbound')]
|
||||
else:
|
||||
res['fields']['payment_method_id']['domain'] = [('payment_type', '=', 'outbound')]
|
||||
return res
|
||||
return {'domain': {'payment_method_id': domain}}
|
||||
return {}
|
||||
|
||||
@api.multi
|
||||
def _prepare_payment_vals(self, invoice):
|
||||
|
||||
@@ -164,14 +164,16 @@ class TestPayment(AccountingTestCase):
|
||||
# One payment for inv_4 (Vendor Bill)
|
||||
inv_4 = self.create_invoice(amount=50, partner=self.partner_agrolait.id, type='in_invoice')
|
||||
|
||||
ids = [inv_1.id, inv_2.id, inv_3.id, inv_4.id]
|
||||
register_payments = self.register_payments_model.with_context(active_ids=ids).create({
|
||||
'payment_date': time.strftime('%Y') + '-07-15',
|
||||
'journal_id': self.bank_journal_euro.id,
|
||||
'payment_method_id': self.payment_method_manual_in.id,
|
||||
})
|
||||
register_payments.create_payments()
|
||||
payment_ids = self.payment_model.search([('invoice_ids', 'in', ids)], order="id desc")
|
||||
ids_out = [inv_1.id, inv_2.id, inv_3.id]
|
||||
ids_in = [inv_4.id]
|
||||
for ids in [ids_out, ids_in]:
|
||||
register_payments = self.register_payments_model.with_context(active_ids=ids).create({
|
||||
'payment_date': time.strftime('%Y') + '-07-15',
|
||||
'journal_id': self.bank_journal_euro.id,
|
||||
'payment_method_id': self.payment_method_manual_in.id,
|
||||
})
|
||||
register_payments.create_payments()
|
||||
payment_ids = self.payment_model.search([('invoice_ids', 'in', ids_out + ids_in)], order="id desc")
|
||||
|
||||
self.assertEqual(len(payment_ids), 4)
|
||||
self.assertAlmostEquals(sum(payment_ids.filtered(lambda r: r.payment_type == 'inbound').mapped('amount')) - sum(payment_ids.filtered(lambda r: r.payment_type == 'outbound').mapped('amount')), 750)
|
||||
|
||||
@@ -144,14 +144,14 @@
|
||||
</div>
|
||||
<group>
|
||||
<field name="invoice_ids" invisible="1"/>
|
||||
<group name="partner_group">
|
||||
<group name="partner_group" invisible="context.get('active_model') == 'account.invoice'">
|
||||
<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, 'default_supplier': payment_type == 'outbound', 'default_customer': payment_type == 'inbound'}"/>
|
||||
</group>
|
||||
<group name="right_column">
|
||||
<field name="payment_date"/>
|
||||
<field name="communication"/>
|
||||
<field name="payment_date"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="amount"/>
|
||||
@@ -162,9 +162,10 @@
|
||||
<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_method_id" string=" " widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
|
||||
<field name="partner_bank_account_id" attrs="{'invisible': [('show_partner_bank_account', '!=', True)], 'required': [('show_partner_bank_account', '=', True)]}" context="{'default_partner_id': partner_id}"/>
|
||||
<field name="payment_method_id" widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
|
||||
<field name="partner_bank_account_id" attrs="{'invisible': [('show_partner_bank_account', '!=', True)], 'required': [('require_partner_bank_account', '=', True)]}" context="{'default_partner_id': partner_id}"/>
|
||||
<field name="show_partner_bank_account" invisible="1"/>
|
||||
<field name="require_partner_bank_account" invisible="1"/>
|
||||
<field name="payment_method_code" invisible="1"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('payment_difference', '=', 0.0)]}">
|
||||
@@ -198,7 +199,7 @@
|
||||
<form string="Register Payment">
|
||||
<group>
|
||||
<group>
|
||||
<field name="payment_method_id" string=" " widget="radio"/>
|
||||
<field name="payment_method_id" widget="radio"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="journal_id" widget="selection"/>
|
||||
@@ -282,54 +283,17 @@
|
||||
<record id="view_account_payment_invoice_form" model="ir.ui.view">
|
||||
<field name="name">account.payment.invoice.form</field>
|
||||
<field name="model">account.payment</field>
|
||||
<field name="inherit_id" ref="view_account_payment_form"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Register Payment">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="payment_type" invisible="1"/>
|
||||
<field name="partner_type" invisible="1"/>
|
||||
<field name="invoice_ids" invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<group>
|
||||
<label for="amount"/>
|
||||
<div name="amount_div" class="o_row">
|
||||
<field name="amount"/>
|
||||
<field name="currency_id" options="{'no_create': True, 'no_open': True}" groups="base.group_multi_currency"/>
|
||||
</div>
|
||||
<field name="journal_id" widget="selection" attrs="{'invisible': [('amount', '=', 0)]}"/>
|
||||
<field name="hide_payment_method" invisible="1"/>
|
||||
<field name="payment_method_id" widget="radio" attrs="{'invisible': ['|', ('hide_payment_method', '=', True), ('amount', '=', 0.0)]}"/>
|
||||
<field name="partner_bank_account_id" attrs="{'invisible': [('show_partner_bank_account', '!=', True)], 'required': [('show_partner_bank_account', '=', True)], 'readonly': [('state', '!=', 'draft')]}" context="{'default_partner_id': partner_id}"/>
|
||||
<field name="show_partner_bank_account" invisible="1"/>
|
||||
<field name="payment_method_code" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_date"/>
|
||||
<field name="communication"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('payment_difference', '=', 0.0)]}">
|
||||
<label for="payment_difference"/>
|
||||
<div>
|
||||
<field name="payment_difference"/>
|
||||
<field name="payment_difference_handling" widget="radio" nolabel="1"/>
|
||||
<div attrs="{'invisible': [('payment_difference_handling','=','open')]}">
|
||||
<label for="writeoff_account_id" class="oe_edit_only" string="Post Difference In"/>
|
||||
<field name="writeoff_account_id" options="{'no_create': True}" string="Post Difference In" attrs="{'required': [('payment_difference_handling', '=', 'reconcile')]}"/>
|
||||
<label for="journal_id" string="Journal" attrs="{'invisible': [('amount', '!=', 0)]}"/>
|
||||
<field name="journal_id" string="Journal" widget="selection" attrs="{'invisible': [('amount', '!=', 0)]}"/>
|
||||
<label for="writeoff_label" class="oe_edit_only" string="Label"/>
|
||||
<field name="writeoff_label" attrs="{'required': [('payment_difference_handling', '=', 'reconcile')]}"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<xpath expr="//header" position='replace'></xpath>
|
||||
<xpath expr="//sheet" position='after'>
|
||||
<footer>
|
||||
<button string='Validate' name="action_validate_invoice_payment" type="object" class="btn-primary"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<button string='Validate' name="post" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ class TestPrintCheck(AccountingTestCase):
|
||||
payment_register.payment_method_id = self.payment_method_check
|
||||
payment = payment_register.save()
|
||||
payment.post()
|
||||
|
||||
return payment
|
||||
|
||||
def test_print_check(self):
|
||||
@@ -80,11 +79,5 @@ class TestPrintCheck(AccountingTestCase):
|
||||
invoices = self.env['account.invoice']
|
||||
for i in range(0, 3):
|
||||
invoices |= self.create_invoice(is_refund=(i % 3 == 0))
|
||||
payment_register = Form(self.env['account.payment.register'].with_context(active_model='account.invoice', active_ids=invoices.ids))
|
||||
payment_register.payment_date = time.strftime('%Y') + '-07-15'
|
||||
payment_register.journal_id = self.bank_journal
|
||||
payment_register.payment_method_id = self.payment_method_check
|
||||
domain = payment_register.save().create_payments()['domain']
|
||||
payment = self.env['account.payment'].search(domain)
|
||||
|
||||
payment = self.create_payment(invoices)
|
||||
self.assertEqual(all(payment.mapped('check_amount_in_words')), True, 'The amount in words is not set on all the payments')
|
||||
|
||||
@@ -29,6 +29,7 @@ class HrExpenseSheetRegisterPaymentWizard(models.TransientModel):
|
||||
hide_payment_method = fields.Boolean(compute='_compute_hide_payment_method',
|
||||
help="Technical field used to hide the payment method if the selected journal has only one available which is 'manual'")
|
||||
show_partner_bank_account = fields.Boolean(compute='_compute_show_partner_bank', help='Technical field used to know whether the field `partner_bank_account_id` needs to be displayed or not in the payments form views')
|
||||
require_partner_bank_account = fields.Boolean(compute='_compute_show_partner_bank', help='Technical field used to know whether the field `partner_bank_account_id` needs to be required or not in the payments form views')
|
||||
|
||||
@api.onchange('partner_id')
|
||||
def _onchange_partner_id(self):
|
||||
@@ -53,6 +54,7 @@ class HrExpenseSheetRegisterPaymentWizard(models.TransientModel):
|
||||
won't be displayed but some modules might change that, depending on the payment type."""
|
||||
for payment in self:
|
||||
payment.show_partner_bank_account = payment.payment_method_id.code in self.env['account.payment']._get_method_codes_using_bank_account()
|
||||
payment.require_partner_bank_account = payment.payment_method_id.code in self.env['account.payment']._get_method_codes_needing_bank_account()
|
||||
|
||||
@api.one
|
||||
@api.depends('journal_id')
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<field name="hide_payment_method" invisible="1"/>
|
||||
<field name="payment_method_id" widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
|
||||
<field name="show_partner_bank_account" invisible="1"/>
|
||||
<field name="partner_bank_account_id" attrs="{'invisible': [('show_partner_bank_account', '!=', True)], 'required': [('show_partner_bank_account', '=', True)]}" domain="[('partner_id', '=', partner_id)]" context="{'default_partner_id': partner_id}"/>
|
||||
<field name="require_partner_bank_account" invisible="1"/>
|
||||
<field name="partner_bank_account_id" attrs="{'invisible': [('show_partner_bank_account', '!=', True)], 'required': [('require_partner_bank_account', '=', True)]}" domain="[('partner_id', '=', partner_id)]" context="{'default_partner_id': partner_id}"/>
|
||||
<label for="amount"/>
|
||||
<div name="amount_div" class="o_row">
|
||||
<field name="amount"/>
|
||||
|
||||
@@ -537,7 +537,7 @@ tour.register('main_flow_tour', {
|
||||
content: _t("Register Payment"),
|
||||
position: "bottom",
|
||||
}, {
|
||||
trigger: ".o_form_sheet_bg .btn-primary",
|
||||
trigger: ".modal-footer .btn-primary",
|
||||
content: _t("Validate"),
|
||||
position: "bottom",
|
||||
}, {
|
||||
@@ -673,11 +673,12 @@ tour.register('main_flow_tour', {
|
||||
position: "bottom",
|
||||
}, {
|
||||
trigger: "select.o_field_widget[name=journal_id]",
|
||||
extra_trigger: ".modal-dialog",
|
||||
content: _t("Select Journal"),
|
||||
position: "bottom",
|
||||
run: 'text Bank(USD)',
|
||||
run: 'text(Bank (USD))',
|
||||
}, {
|
||||
trigger: ".btn-primary",
|
||||
trigger: ".modal-footer .btn-primary",
|
||||
content: _t("Validate"),
|
||||
position: "bottom",
|
||||
}, {
|
||||
|
||||
Reference in New Issue
Block a user