[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:
wan
2019-04-04 12:46:20 +00:00
parent 3c2e3b8c5a
commit 6940cfddbc
8 changed files with 59 additions and 128 deletions
+1 -1
View File
@@ -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):
+26 -58
View File
@@ -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):
+10 -8
View File
@@ -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)
+13 -49
View File
@@ -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",
}, {