[IMP] account: credit note usability

Task 2038326

* Tick the credit note sequence by default on the customer invoices and vendor bills journals
* Write Customer Invoice/Vendor Bill/Credit Note/Customer refund at the top of the document
* The reference field should be printed on the credit note pdf (interesting because it gives source and reason)
* If the document is a credit note, there shouldn't be any payment information on the pdf (the customer doesn't have to pay you) (currently you see the "payment communication" the customer is supposed to use)
* Rename Credit Note to Refund on dashboard
* Add tooltip on payment widget

closes odoo/odoo#35231

Signed-off-by: Cedric Snauwaert (csn) <csn@openerp.com>
This commit is contained in:
wan
2019-07-31 14:39:22 +00:00
parent b66d84119c
commit 2d086f5d8f
8 changed files with 33 additions and 21 deletions
+2 -2
View File
@@ -8,7 +8,7 @@
<record id="email_template_edi_invoice" model="mail.template">
<field name="name">Invoice: Send by email</field>
<field name="model_id" ref="account.model_account_move"/>
<field name="email_from">${(object.user_id.email_formatted or user.email_formatted) |safe}</field>
<field name="email_from">${(object.invoice_user_id.email_formatted or user.email_formatted) |safe}</field>
<field name="partner_to">${object.partner_id.id}</field>
<field name="subject">${object.company_id.name} Invoice (Ref ${object.name or 'n/a'})</field>
<field name="body_html" type="html">
@@ -21,7 +21,7 @@
${object.partner_id.name},
% endif
<br /><br />
Here is your
Here is your
% if object.name:
invoice <strong>${object.name}</strong>
% else:
+8 -1
View File
@@ -556,7 +556,7 @@ class AccountJournal(models.Model):
help='The next sequence number will be used for the next invoice.',
compute='_compute_seq_number_next',
inverse='_inverse_seq_number_next')
refund_sequence_number_next = fields.Integer(string='Credit Notes: Next Number',
refund_sequence_number_next = fields.Integer(string='Credit Notes Next Number',
help='The next sequence number will be used for the next credit note.',
compute='_compute_refund_seq_number_next',
inverse='_inverse_refund_seq_number_next')
@@ -686,6 +686,10 @@ class AccountJournal(models.Model):
if not self.default_debit_account_id:
self.default_debit_account_id = self.default_credit_account_id
@api.onchange('type')
def _onchange_type(self):
self.refund_sequence = self.type in ('sale', 'purchase')
def _get_alias_values(self, type, alias_name=None):
if not alias_name:
alias_name = self.name
@@ -872,6 +876,7 @@ class AccountJournal(models.Model):
if not vals['code']:
raise UserError(_("Cannot generate an unused journal code. Please fill the 'Shortcode' field."))
# Create a default debit/credit account if not given
default_account = vals.get('default_debit_account_id') or vals.get('default_credit_account_id')
company = self.env['res.company'].browse(company_id)
@@ -886,6 +891,8 @@ class AccountJournal(models.Model):
if not vals.get('loss_account_id'):
vals['loss_account_id'] = company.default_cash_difference_expense_account_id.id
if 'refund_sequence' not in vals:
vals['refund_sequence'] = vals['type'] in ('sale', 'purchase')
# We just need to create the relevant sequences according to the chosen options
if not vals.get('sequence_id'):
@@ -14,15 +14,15 @@
<tr>
<t t-if="outstanding">
<td>
<a title="assign to invoice" role="button" class="oe_form_field btn btn-link outstanding_credit_assign" t-att-data-id="line.id" style="margin-right: 10px;" href="#">Add</a>
<a title="assign to invoice" role="button" class="oe_form_field btn btn-link outstanding_credit_assign" t-att-data-id="line.id" style="margin-right: 10px;" href="#" data-toggle="tooltip">Add</a>
</td>
<td style="max-width: 10em;">
<div class="oe_form_field" style="margin-right: 30px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;" t-att-title="line.title"><t t-esc="line.journal_name"></t></div>
<div class="oe_form_field" style="margin-right: 30px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;" t-att-title="line.journal_name" data-toggle="tooltip"><t t-esc="line.journal_name"></t></div>
</td>
</t>
<t t-if="!outstanding">
<td>
<a role="button" tabindex="0" class="js_payment_info fa fa-info-circle" t-att-index="line.index" style="margin-right:5px;" aria-label="Info" title="Info"></a>
<a role="button" tabindex="0" class="js_payment_info fa fa-info-circle" t-att-index="line.index" style="margin-right:5px;" aria-label="Info" title="Info" data-toggle="tooltip"></a>
</td>
<td>
<i class="o_field_widget text-right o_payment_label">Paid on <t t-esc="line.date"></t></i>
@@ -33,7 +33,7 @@
<t t-if="line.position === 'before'">
<t t-esc="line.currency"/>
</t>
<t t-esc="line.amount"></t>
<t t-esc="line.amount"></t>
<t t-if="line.position === 'after'">
<t t-esc="line.currency"/>
</t>
@@ -70,7 +70,7 @@
<t t-if="position === 'before'">
<t t-esc="currency"/>
</t>
<t t-esc="amount"></t>
<t t-esc="amount"></t>
<t t-if="position === 'after'">
<t t-esc="currency"/>
</t>
@@ -11,7 +11,7 @@ class TestAccountMoveInRefundOnchanges(InvoiceTestCommon):
@classmethod
def setUpClass(cls):
super(TestAccountMoveInRefundOnchanges, cls).setUpClass()
cls.invoice = cls.init_invoice('in_refund')
cls.product_line_vals_1 = {
@@ -813,7 +813,7 @@ class TestAccountMoveInRefundOnchanges(InvoiceTestCommon):
def test_in_refund_line_onchange_sequence_number_1(self):
self.assertRecordValues(self.invoice, [{
'invoice_sequence_number_next': '0001',
'invoice_sequence_number_next_prefix': 'BILL/2019/',
'invoice_sequence_number_next_prefix': 'RBILL/2019/',
}])
move_form = Form(self.invoice)
@@ -822,17 +822,17 @@ class TestAccountMoveInRefundOnchanges(InvoiceTestCommon):
self.assertRecordValues(self.invoice, [{
'invoice_sequence_number_next': '0042',
'invoice_sequence_number_next_prefix': 'BILL/2019/',
'invoice_sequence_number_next_prefix': 'RBILL/2019/',
}])
self.invoice.post()
self.assertRecordValues(self.invoice, [{'name': 'BILL/2019/0042'}])
self.assertRecordValues(self.invoice, [{'name': 'RBILL/2019/0042'}])
invoice_copy = self.invoice.copy()
invoice_copy.post()
self.assertRecordValues(invoice_copy, [{'name': 'BILL/2019/0043'}])
self.assertRecordValues(invoice_copy, [{'name': 'RBILL/2019/0043'}])
def test_in_refund_onchange_past_invoice_1(self):
copy_invoice = self.invoice.copy()
@@ -11,7 +11,7 @@ class TestAccountMoveOutRefundOnchanges(InvoiceTestCommon):
@classmethod
def setUpClass(cls):
super(TestAccountMoveOutRefundOnchanges, cls).setUpClass()
cls.invoice = cls.init_invoice('out_refund')
cls.product_line_vals_1 = {
@@ -813,7 +813,7 @@ class TestAccountMoveOutRefundOnchanges(InvoiceTestCommon):
def test_out_refund_line_onchange_sequence_number_1(self):
self.assertRecordValues(self.invoice, [{
'invoice_sequence_number_next': '0001',
'invoice_sequence_number_next_prefix': 'INV/2019/',
'invoice_sequence_number_next_prefix': 'RINV/2019/',
}])
move_form = Form(self.invoice)
@@ -822,17 +822,17 @@ class TestAccountMoveOutRefundOnchanges(InvoiceTestCommon):
self.assertRecordValues(self.invoice, [{
'invoice_sequence_number_next': '0042',
'invoice_sequence_number_next_prefix': 'INV/2019/',
'invoice_sequence_number_next_prefix': 'RINV/2019/',
}])
self.invoice.post()
self.assertRecordValues(self.invoice, [{'name': 'INV/2019/0042'}])
self.assertRecordValues(self.invoice, [{'name': 'RINV/2019/0042'}])
invoice_copy = self.invoice.copy()
invoice_copy.post()
self.assertRecordValues(invoice_copy, [{'name': 'INV/2019/0043'}])
self.assertRecordValues(invoice_copy, [{'name': 'RINV/2019/0043'}])
def test_out_refund_create_1(self):
# Test creating an account_move with the least information.
@@ -129,7 +129,7 @@
</div>
<div>
<a t-if="journal_type == 'sale'" type="object" name="open_action" context="{'action_name': 'action_move_out_refund_type'}">Credit Notes</a>
<a t-if="journal_type == 'purchase'" type="object" name="open_action" context="{'action_name': 'action_move_in_refund_type'}">Credit Notes</a>
<a t-if="journal_type == 'purchase'" type="object" name="open_action" context="{'action_name': 'action_move_in_refund_type'}">Refund</a>
</div>
<div>
<a type="object" name="action_open_reconcile">Payments Matching</a>
@@ -152,7 +152,7 @@
<div>
<a type="object" name="action_create_new" context="{'refund':True}">
<span t-if="journal_type == 'sale'">Credit Note</span>
<span t-if="journal_type == 'purchase'">Credit Note Bill</span>
<span t-if="journal_type == 'purchase'">Refund</span>
</a>
</div>
</div>
@@ -518,6 +518,7 @@
<div>
<!-- Invoice draft header -->
<span class="o_form_label"><field name="type" attrs="{'invisible': ['|', ('type', '=', 'entry'), ('state', '=', 'draft')]}" readonly="1" nolabel="1"/></span>
<span class="o_form_label" attrs="{'invisible': ['|', '|', ('type', '!=', 'out_invoice'), ('state', '!=', 'draft'), ('name', '!=', '/')]}">Draft Invoice</span>
<span class="o_form_label" attrs="{'invisible': ['|', '|', ('type', '!=', 'out_refund'), ('state', '!=', 'draft'), ('name', '!=', '/')]}">Draft Credit Note</span>
<span class="o_form_label" attrs="{'invisible': ['|', '|', ('type', '!=', 'in_invoice'), ('state', '!=', 'draft'), ('name', '!=', '/')]}">Draft Bill</span>
+5 -1
View File
@@ -40,6 +40,10 @@
<strong>Customer Code:</strong>
<p class="m-0" t-field="o.partner_id.ref"/>
</div>
<div class="col-auto mw-100 mb-2" t-if="o.ref" name="reference">
<strong>Reference:</strong>
<p class="m-0" t-field="o.ref"/>
</div>
</div>
<t t-set="display_discount" t-value="any([l.discount for l in o.invoice_line_ids])"/>
@@ -164,7 +168,7 @@
</div>
</div>
</div>
<p>
<p t-if="o.type in ('out_invoice', 'in_refund')">
Please use the following communication for your payment : <b><span t-field="o.invoice_payment_ref"/></b>
</p>
<p t-if="o.narration" name="comment">