Permalink
Browse files

[IMP] account: refactor account.payment

  • Loading branch information...
william-andre committed Dec 6, 2018
1 parent b8c4b42 commit 81310f3ce0f576f11c216ecc957ccf3dfceae6aa
@@ -35,9 +35,11 @@ class account_abstract_payment(models.AbstractModel):
_description = "Contains the logic shared between models which allows to register payments"
invoice_ids = fields.Many2many('account.invoice', string='Invoices', copy=False)
invoice_number = fields.Integer(compute="_compute_invoice_number")
multi = fields.Boolean(string='Multi',
help='Technical field indicating if the user selected invoices from multiple partners or from different types.')
state = fields.Selection([('draft', 'Draft'), ('posted', 'Posted'), ('sent', 'Sent'), ('reconciled', 'Reconciled'), ('cancelled', 'Cancelled')], readonly=True, default='draft', copy=False, string="Status")
payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money')], string='Payment Type', required=True)
payment_method_id = fields.Many2one('account.payment.method', string='Payment Method Type', required=True, oldname="payment_method",
help="Manual: Get paid by cash, check or any other method outside of Odoo.\n"\
@@ -120,6 +122,11 @@ def _check_amount(self):
@api.model
def _get_method_codes_using_bank_account(self):
return []
@api.depends('invoice_ids')
def _compute_invoice_number(self):
for payment in self:
payment.invoice_number = len(payment.invoice_ids)
@api.depends('payment_method_code')
def _compute_show_partner_bank(self):
@@ -140,7 +147,7 @@ def _compute_hide_payment_method(self):
or payment.journal_id.outbound_payment_method_ids
payment.hide_payment_method = len(journal_payment_methods) == 1 and journal_payment_methods[0].code == 'manual'
@api.depends('invoice_ids', 'amount', 'payment_date', 'currency_id')
@api.depends('invoice_ids', 'amount', 'payment_date', 'currency_id') # no payment_type ?
def _compute_payment_difference(self):
for pay in self.filtered(lambda p: p.invoice_ids):
payment_amount = -pay.amount if pay.payment_type == 'outbound' else pay.amount
@@ -151,7 +158,7 @@ def _onchange_journal(self):
if self.journal_id:
# Set default payment method (we consider the first to be the default one)
payment_methods = self.payment_type == 'inbound' and self.journal_id.inbound_payment_method_ids or self.journal_id.outbound_payment_method_ids
payment_methods_list = payment_methods.ids
payment_methods_list = payment_methods.ids #ternary more readable
default_payment_method_id = self.env.context.get('default_payment_method_id')
if default_payment_method_id:
@@ -161,7 +168,8 @@ def _onchange_journal(self):
self.payment_method_id = payment_methods and payment_methods[0] or False
# Set payment method domain (restrict to methods enabled for the journal and to selected payment type)
payment_type = self.payment_type in ('outbound', 'transfer') and 'outbound' or 'inbound'
payment_type = self.payment_type in ('outbound', 'transfer') and 'outbound' or 'inbound' # transfer not defined in the class
#if i add paypal, empty/useless field appears, can only select in multi
return {'domain': {'payment_method_id': [('payment_type', '=', payment_type), ('id', 'in', payment_methods_list)]}}
return {}
@@ -208,7 +216,7 @@ def _onchange_amount(self):
@api.onchange('currency_id')
def _onchange_currency(self):
self.amount = abs(self._compute_payment_amount())
self.amount = abs(self._compute_payment_amount()) #never check inbound/outbound ?
# Set by default the first liquidity journal having this currency if exists.
journal = self.env['account.journal'].search(
@@ -217,7 +225,7 @@ def _onchange_currency(self):
return {'value': {'journal_id': journal.id}}
@api.multi
def _compute_payment_amount(self, invoices=None, currency=None):
def _compute_payment_amount(self, invoices=None, currency=None): #why not return directly if multi here ?
'''Compute the total amount for the payment wizard.
:param invoices: If not specified, pick all the invoices.
@@ -232,6 +240,7 @@ def _compute_payment_amount(self, invoices=None, currency=None):
# Get the payment currency
if not currency:
currency = self.currency_id or self.journal_id.currency_id or self.journal_id.company_id.currency_id or invoices and invoices[0].currency_id
#company currency_id required, why check invoice ?
# Avoid currency rounding issues by summing the amounts according to the company_currency_id before
total = 0.0
@@ -266,7 +275,7 @@ def _compute_show_communication_field(self):
or record.group_invoices and len(record.mapped('invoice_ids.partner_id.commercial_partner_id')) == 1
@api.onchange('journal_id')
def _onchange_journal(self):
def _onchange_journal(self): #why, and why only in transient ? i dont think it is necessary anymore https://github.com/odoo/odoo/commit/ec7109c
res = super(account_register_payments, self)._onchange_journal()
active_ids = self._context.get('active_ids')
invoices = self.env['account.invoice'].browse(active_ids)
@@ -318,9 +327,9 @@ def _prepare_payment_vals(self, invoices):
:param invoices: The invoices that should have the same commercial partner and the same type.
:return: The payment values as a dictionary.
'''
amount = self._compute_payment_amount(invoices=invoices) if self.multi else self.amount
amount = self._compute_payment_amount(invoices=invoices) if self.multi else self.amount #check self.multi in _compute_payment_amount
payment_type = ('inbound' if amount > 0 else 'outbound') if self.multi else self.payment_type
bank_account = self.multi and invoices[0].partner_bank_id or self.partner_bank_account_id
bank_account = self.multi and invoices[0].partner_bank_id or self.partner_bank_account_id #why not always invoice.partner_bank_id ?
pmt_communication = self.show_communication_field and self.communication \
or self.group_invoices and ' '.join([inv.reference or inv.number for inv in invoices]) \
or invoices[0].reference # in this case, invoices contains only one element, since group_invoices is False
@@ -340,12 +349,12 @@ def _prepare_payment_vals(self, invoices):
}
@api.multi
def get_payments_vals(self):
def get_payments_vals(self): # (shouldnt it be private ?)
'''Compute the values for payments.
:return: a list of payment values (dictionary).
'''
if self.multi:
if self.multi: #groupby_invoices should return a valid dict even if not multi, condition unecessary, _prepare_payment_vals unecessary
groups = self._groupby_invoices()
return [self._prepare_payment_vals(invoices) for invoices in groups.values()]
return [self._prepare_payment_vals(self.invoice_ids)]
@@ -395,13 +404,12 @@ def _get_move_reconciled(self):
for aml in payment.move_line_ids.filtered(lambda x: x.account_id.reconcile):
if not aml.reconciled:
rec = False
break
payment.move_reconciled = rec
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', readonly=True)
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', readonly=True) #why not just use journal_id.company_id or put it in the abstract ?
name = fields.Char(readonly=True, copy=False) # The name is attributed upon post()
state = fields.Selection([('draft', 'Draft'), ('posted', 'Posted'), ('sent', 'Sent'), ('reconciled', 'Reconciled'), ('cancelled', 'Cancelled')], readonly=True, default='draft', copy=False, string="Status")
payment_type = fields.Selection(selection_add=[('transfer', 'Internal Transfer')])
payment_type = fields.Selection(selection_add=[('transfer', 'Internal Transfer')]) #Why only in account_payment ? We even check for it in the abstract class...
payment_reference = fields.Char(copy=False, readonly=True, help="Reference of the document used to issue this payment. Eg. check number, file name, etc.")
move_name = fields.Char(string='Journal Entry Name', readonly=True,
default=False, copy=False,
@@ -470,14 +478,14 @@ def _compute_reconciled_invoice_ids(self):
record.move_line_ids.mapped('matched_credit_ids.credit_move_id.invoice_id'))
record.has_invoices = bool(record.reconciled_invoice_ids)
@api.onchange('partner_type')
@api.onchange('partner_type') #why only in account_payment ?
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')
@api.onchange('payment_type') #why only in account_payment ? it doesnt even check transfer defined here
def _onchange_payment_type(self):
if not self.invoice_ids:
# Set default partner type for the payment type
@@ -552,10 +560,6 @@ def button_invoices(self):
'domain': [('id', 'in', [x.id for x in self.reconciled_invoice_ids])],
}
@api.multi
def button_dummy(self):
return True
@api.multi
def unreconcile(self):
""" Set back the payments in 'posted' or 'sent' state, without deleting the journal entries.
@@ -639,17 +643,6 @@ def post(self):
def action_draft(self):
return self.write({'state': 'draft'})
def action_validate_invoice_payment(self):
""" Posts a payment used to pay an invoice. This function only posts the
payment by default but can be overridden to apply specific post or pre-processing.
It is called by the "validate" button of the popup window
triggered on invoice form by the "Register Payment" button.
"""
if any(len(record.invoice_ids) != 1 for record in self):
# For multiple invoices, there is account.register.payments wizard
raise UserError(_("This method should only be called to process a single invoice's payment."))
return self.post()
def _create_payment_entry(self, amount):
""" Create a journal entry corresponding to a payment, if the payment references invoice(s) they are reconciled.
Return the journal entry.
@@ -248,73 +248,6 @@
<menuitem action="action_account_payments" id="menu_action_account_payments_receivable" parent="account.menu_finance_receivables" sequence="15"/>
<menuitem action="action_account_payments_payable" id="menu_action_account_payments_payable" parent="account.menu_finance_payables" sequence="20"/>
<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="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" 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>
<footer>
<button string='Validate' name="action_validate_invoice_payment" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_account_invoice_payment" model="ir.actions.act_window">
<field name="name">Register Payment</field>
<field name="res_model">account.payment</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_account_payment_invoice_form"/>
<field name="context">{'default_invoice_ids': [(4, active_id, None)]}</field>
<field name="target">new</field>
</record>
<!-- Register payment from several invoices -->
<record id="view_account_payment_from_invoices" model="ir.ui.view">
<field name="name">account.register.payments.wizard</field>
<field name="model">account.register.payments</field>
@@ -326,8 +259,10 @@
<field name="invoice_ids" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="multi" invisible="1"/>
<field name="state" invisible="1"/>
<field name="invoice_number" invisible="1"/>
<group>
<label for="amount"/>
<label for="amount" attrs="{'readonly': [('multi', '=', True)]}"/>
<div name="amount_div" class="o_row">
<field name="amount" attrs="{'readonly': [('multi', '=', True)]}"/>
<field name="currency_id"
@@ -338,13 +273,13 @@
<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)]}" context="{'default_partner_id': partner_id}"/>
<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="group_invoices"/>
<field name="group_invoices" attrs="{'invisible': [('invoice_number', '=', 1)]}"/>
<field name="show_communication_field" invisible="1"/>
<field name="communication" attrs="{'invisible': [('show_communication_field', '=', False)]}"/>
<p colspan="2" attrs="{'invisible': [('show_communication_field', '=', True)]}">Memo will be computed from invoices</p>
@@ -372,6 +307,16 @@
</form>
</field>
</record>
<record id="action_account_invoice_payment" model="ir.actions.act_window">
<field name="name">Register Payment</field>
<field name="res_model">account.register.payments</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_account_payment_from_invoices"/>
<field name="context">{'default_invoice_ids': [(4, active_id, None)]}</field>
<field name="target">new</field>
</record>
<act_window
id="action_account_payment_from_invoices"
@@ -19,17 +19,6 @@
</field>
</record>
<record id="view_account_payment_invoice_form_inherited" model="ir.ui.view">
<field name="name">account.payment.invoice.form.inherited</field>
<field name="model">account.payment</field>
<field name="inherit_id" ref="account.view_account_payment_invoice_form" />
<field name="arch" type="xml">
<xpath expr="//div[@name='amount_div']" position="after">
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_printing')]}"/>
</xpath>
</field>
</record>
<record id="view_account_payment_from_invoices_inherited" model="ir.ui.view">
<field name="name">account.register.payments.wizard.inherited</field>
<field name="model">account.register.payments</field>
Oops, something went wrong.

0 comments on commit 81310f3

Please sign in to comment.