[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:
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user