[MERGE] account: menus for credit note + avoid negative invoices
This commit is contained in:
@@ -9,7 +9,7 @@ from odoo import api, fields, models, _
|
||||
from odoo.tools import float_is_zero, float_compare
|
||||
from odoo.tools.misc import formatLang
|
||||
|
||||
from odoo.exceptions import UserError, RedirectWarning, ValidationError
|
||||
from odoo.exceptions import UserError, RedirectWarning, ValidationError, Warning
|
||||
|
||||
import odoo.addons.decimal_precision as dp
|
||||
import logging
|
||||
@@ -58,6 +58,12 @@ class AccountInvoice(models.Model):
|
||||
self.amount_total_signed = self.amount_total * sign
|
||||
self.amount_untaxed_signed = amount_untaxed_signed * sign
|
||||
|
||||
@api.onchange('amount_total')
|
||||
def _onchange_amount_total(self):
|
||||
for inv in self:
|
||||
if inv.amount_total < 0:
|
||||
raise Warning(_('You cannot validate an invoice with a negative total amount. You should create a credit note instead.'))
|
||||
|
||||
@api.model
|
||||
def _default_journal(self):
|
||||
if self._context.get('default_journal_id', False):
|
||||
@@ -573,6 +579,8 @@ class AccountInvoice(models.Model):
|
||||
to_open_invoices = self.filtered(lambda inv: inv.state != 'open')
|
||||
if to_open_invoices.filtered(lambda inv: inv.state != 'draft'):
|
||||
raise UserError(_("Invoice must be in draft state in order to validate it."))
|
||||
if to_open_invoices.filtered(lambda inv: inv.amount_total < 0):
|
||||
raise UserError(_("You cannot validate an invoice with a negative total amount. You should create a credit note instead."))
|
||||
to_open_invoices.action_date_assign()
|
||||
to_open_invoices.action_move_create()
|
||||
return to_open_invoices.invoice_validate()
|
||||
|
||||
@@ -610,7 +610,7 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
|
||||
<field eval="False" name="view_id"/>
|
||||
<field name="domain">[('type','in',('out_invoice', 'out_refund'))]</field>
|
||||
<field name="domain">[('type','=','out_invoice')]</field>
|
||||
<field name="context">{'type':'out_invoice', 'journal_type': 'sale'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help" type="html">
|
||||
@@ -645,13 +645,51 @@
|
||||
|
||||
<menuitem action="action_invoice_tree1" id="menu_action_invoice_tree1" parent="menu_finance_receivables" sequence="1"/>
|
||||
|
||||
<record id="action_invoice_out_refund" model="ir.actions.act_window">
|
||||
<field name="name">Customer Credit Notes</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
|
||||
<field eval="False" name="view_id"/>
|
||||
<field name="domain">[('type','=','out_refund')]</field>
|
||||
<field name="context">{'default_type': 'out_refund', 'journal_type': 'sale'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a credit note.
|
||||
</p><p>
|
||||
Note that the easiest way to create a credit note is to do it directly form
|
||||
the customer invoice, to refund it totally or partially.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_invoice_out_refund_tree" model="ir.actions.act_window.view">
|
||||
<field eval="1" name="sequence"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="invoice_tree"/>
|
||||
<field name="act_window_id" ref="action_invoice_out_refund"/>
|
||||
</record>
|
||||
|
||||
<record id="action_invoice_out_refund_form" model="ir.actions.act_window.view">
|
||||
<field eval="2" name="sequence"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="invoice_form"/>
|
||||
<field name="act_window_id" ref="action_invoice_out_refund"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_invoice_out_refund"
|
||||
id="menu_action_invoice_out_refund"
|
||||
parent="menu_finance_receivables"
|
||||
sequence="1"/>
|
||||
|
||||
<record id="action_invoice_tree2" model="ir.actions.act_window">
|
||||
<field name="name">Vendor Bills</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
|
||||
<field eval="False" name="view_id"/>
|
||||
<field name="domain">[('type','in',('in_invoice', 'in_refund'))]</field>
|
||||
<field name="domain">[('type','=','in_invoice')]</field>
|
||||
<field name="context">{'default_type': 'in_invoice', 'type': 'in_invoice', 'journal_type': 'purchase'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help" type="html">
|
||||
@@ -680,6 +718,42 @@
|
||||
|
||||
<menuitem action="action_invoice_tree2" id="menu_action_invoice_tree2" parent="menu_finance_payables" sequence="1"/>
|
||||
|
||||
|
||||
<record id="action_invoice_in_refund" model="ir.actions.act_window">
|
||||
<field name="name">Vendor Credit Notes</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
|
||||
<field eval="False" name="view_id"/>
|
||||
<field name="domain">[('type','=','in_refund')]</field>
|
||||
<field name="context">{'default_type': 'in_refund', 'journal_type': 'purchase'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to record a new vendor credit note.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_invoice_in_refund_tree" model="ir.actions.act_window.view">
|
||||
<field eval="1" name="sequence"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="invoice_supplier_tree"/>
|
||||
<field name="act_window_id" ref="action_invoice_in_refund"/>
|
||||
</record>
|
||||
|
||||
<record id="action_invoice_in_refund_form" model="ir.actions.act_window.view">
|
||||
<field eval="2" name="sequence"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="invoice_supplier_form"/>
|
||||
<field name="act_window_id" ref="action_invoice_in_refund"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_invoice_in_refund"
|
||||
id="menu_action_invoice_in_refund"
|
||||
parent="menu_finance_payables"
|
||||
sequence="1"/>
|
||||
|
||||
<act_window
|
||||
id="act_account_journal_2_account_invoice_opened"
|
||||
name="Unpaid Invoices"
|
||||
|
||||
@@ -108,8 +108,10 @@ class AccountInvoiceRefund(models.TransientModel):
|
||||
if inv_refund.payment_term_id.id:
|
||||
inv_refund._onchange_payment_term_date_invoice()
|
||||
created_inv.append(inv_refund.id)
|
||||
xml_id = (inv.type in ['out_refund', 'out_invoice']) and 'action_invoice_tree1' or \
|
||||
(inv.type in ['in_refund', 'in_invoice']) and 'action_invoice_tree2'
|
||||
xml_id = inv.type == 'out_invoice' and 'action_invoice_out_refund' or \
|
||||
inv.type == 'out_refund' and 'action_invoice_tree1' or \
|
||||
inv.type == 'in_invoice' and 'action_invoice_in_refund' or \
|
||||
inv.type == 'in_refund' and 'action_invoice_tree2'
|
||||
# Put the reason in the chatter
|
||||
subject = _("Invoice refund")
|
||||
body = description
|
||||
|
||||
Reference in New Issue
Block a user