Skip to content

Commit

Permalink
Merge pull request #367 from Tecnativa/11.0-account_invoice_refund_li…
Browse files Browse the repository at this point in the history
…nk-no_conflict

[FIX] account_invoice_refund_link: Don't choke with standard fields
  • Loading branch information
StefanRijnhart authored Apr 2, 2018
2 parents 581c44b + f670ef7 commit cdbf593
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 140 deletions.
18 changes: 9 additions & 9 deletions account_invoice_refund_link/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
Link refund invoice with original
=================================

This module links customer and supplier refunds with the invoice that originate
them (and invoice lines).
This module shows the links between refunds and their original invoices in the
invoice form and also keep track of refund lines and their original invoice
lines.

Usage
=====

This module creates in the invoice form a new 'Refund' page.
This module creates in the invoice form a new 'Refunds' page when the invoice
has some refunds. It shows a line for each refund invoice with main
information.

In case of refund invoices this new page shows refund reason and original
invoice information.

In case of original invoices this new page shows a line for each refund
invoice with main information.
For refunds, it shows in "Other information" page the refund reason and
original invoice link.

.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
Expand All @@ -44,7 +44,7 @@ Contributors
------------

* Pexego Sistemas Informáticos. (http://pexego.es)
* Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Antonio Espinosa <[email protected]>
* Luis M. Ontalba <[email protected]>

Expand Down
1 change: 0 additions & 1 deletion account_invoice_refund_link/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
Expand Down
3 changes: 1 addition & 2 deletions account_invoice_refund_link/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2004-2011 Pexego Sistemas Informáticos. (http://pexego.es)
# Copyright 2016 Antonio Espinosa <[email protected]>
# Copyright 2014-2017 Pedro M. Baeza <[email protected]>
Expand All @@ -7,7 +6,7 @@
{
"name": "Link refund invoice with original",
"summary": "Link refund invoice with its original invoice",
"version": "11.0.1.0.0",
"version": "11.0.2.0.0",
"category": "Accounting & Finance",
"website": "https://odoo-community.org/",
"author": "Pexego, "
Expand Down
31 changes: 7 additions & 24 deletions account_invoice_refund_link/hooks.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Antonio Espinosa <[email protected]>
# Copyright 2017 Pedro M. Baeza <[email protected]>
# Copyright 2017-2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging
from openerp import _, api, SUPERUSER_ID
from odoo import api, SUPERUSER_ID

_logger = logging.getLogger(__name__)


def _invoice_match(env, invoice):
inv_type = 'out_invoice' if invoice.type == 'out_refund' else 'in_invoice'
return env['account.invoice'].search([
('type', '=', inv_type),
('number', '=ilike', invoice.origin),
('company_id', '=', invoice.company_id.id),
])


def match_origin_lines(refund, invoice):
def match_origin_lines(refund):
"""Try to match lines by product or by description."""
invoice = refund.refund_invoice_id
invoice_lines = invoice.invoice_line_ids
for refund_line in refund.invoice_line_ids:
for invoice_line in invoice_lines:
Expand All @@ -30,7 +21,7 @@ def match_origin_lines(refund, invoice):
)
if match:
invoice_lines -= invoice_line
invoice_line.origin_line_ids = [(6, 0, refund_line.ids)]
refund_line.origin_line_ids = [(6, 0, invoice_line.ids)]
break
if not invoice_lines:
break
Expand All @@ -42,15 +33,7 @@ def post_init_hook(cr, registry):
# Linking all refund invoices to its original invoices
refunds = env['account.invoice'].search([
('type', 'in', ('out_refund', 'in_refund')),
('origin_invoice_ids', '=', False),
('refund_invoice_id', '!=', False),
])
_logger.info("Linking %d refund invoices", len(refunds))
for refund in refunds:
original = _invoice_match(env, refund)
if not original: # pragma: no cover
continue
refund.write({
'origin_invoice_ids': [(6, 0, original.ids)],
'refund_reason': _('Auto'),
})
match_origin_lines(refund, original)
match_origin_lines(refund)
1 change: 0 additions & 1 deletion account_invoice_refund_link/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import account_invoice
20 changes: 2 additions & 18 deletions account_invoice_refund_link/models/account_invoice.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2004-2011 Pexego Sistemas Informáticos. (http://pexego.es)
# Copyright 2016 Antonio Espinosa <[email protected]>
# Copyright 2014-2017 Pedro M. Baeza <[email protected]>
# Copyright 2014-2018 Pedro M. Baeza <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, models, fields
Expand All @@ -11,30 +10,15 @@ class AccountInvoice(models.Model):
_inherit = 'account.invoice'

refund_reason = fields.Text(string="Refund reason")
origin_invoice_ids = fields.Many2many(
comodel_name='account.invoice', column1='refund_invoice_id',
column2='original_invoice_id', relation='account_invoice_refunds_rel',
string="Original invoice", readonly=True,
help="Original invoice to which this refund invoice is referred to",
copy=False,
)
refund_invoice_ids = fields.Many2many(
comodel_name='account.invoice', column1='original_invoice_id',
column2='refund_invoice_id', relation='account_invoice_refunds_rel',
string="Refund invoices", readonly=True,
help="Refund invoices created from this invoice",
copy=False,
)

@api.model
def _prepare_refund(self, invoice, date_invoice=None, date=None,
description=None, journal_id=None):
"""Add link in the refund to the origin invoice and origin lines."""
"""Add link in the refund to the origin invoice lines."""
res = super(AccountInvoice, self)._prepare_refund(
invoice, date_invoice=date_invoice, date=date,
description=description, journal_id=journal_id,
)
res['origin_invoice_ids'] = [(6, 0, invoice.ids)]
res['refund_reason'] = description
refund_lines_vals = res['invoice_line_ids']
for i, line in enumerate(invoice.invoice_line_ids):
Expand Down
1 change: 0 additions & 1 deletion account_invoice_refund_link/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Antonio Espinosa <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

Expand Down
12 changes: 4 additions & 8 deletions account_invoice_refund_link/tests/test_invoice_refund_link.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Antonio Espinosa <[email protected]>
# Copyright 2014-2017 Pedro M. Baeza <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
Expand Down Expand Up @@ -49,7 +48,6 @@ def _test_refund_link(self):
self.assertTrue(self.invoice.refund_invoice_ids)
refund = self.invoice.refund_invoice_ids[0]
self.assertEqual(refund.refund_reason, self.refund_reason)
self.assertEqual(refund.origin_invoice_ids[0], self.invoice)
self.assertEqual(len(self.invoice.invoice_line_ids),
len(self.invoice_lines))
self.assertEqual(len(refund.invoice_line_ids),
Expand All @@ -66,12 +64,12 @@ class TestInvoiceRefundLink(TestInvoiceRefundLinkBase):
def test_post_init_hook(self):
self.assertTrue(self.invoice.refund_invoice_ids)
refund = self.invoice.refund_invoice_ids[0]
refund.write({
'origin_invoice_ids': [(5, False, False)],
refund.invoice_line_ids.write({
'origin_line_ids': [(5, False, False)],
})
self.assertFalse(refund.origin_invoice_ids)
self.assertFalse(refund.mapped('invoice_line_ids.origin_line_ids'))
post_init_hook(self.env.cr, None)
self.refund_reason = 'Auto'
self.refund_reason = 'The refund reason'
self._test_refund_link()

def test_refund_link(self):
Expand All @@ -80,7 +78,6 @@ def test_refund_link(self):
def test_invoice_copy(self):
refund = self.invoice.refund_invoice_ids[0]
self.invoice.copy()
self.assertEqual(refund.origin_invoice_ids, self.invoice)
self.assertEqual(
refund.mapped('invoice_line_ids.origin_line_ids'),
self.invoice.mapped('invoice_line_ids'),
Expand All @@ -89,7 +86,6 @@ def test_invoice_copy(self):
def test_refund_copy(self):
refund = self.invoice.refund_invoice_ids[0]
refund.copy()
self.assertEqual(self.invoice.refund_invoice_ids, refund)
self.assertEqual(
self.invoice.mapped('invoice_line_ids.refund_line_ids'),
refund.mapped('invoice_line_ids'),
Expand Down
132 changes: 56 additions & 76 deletions account_invoice_refund_link/views/account_invoice_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,36 @@
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page name="refunds" string="Refunds">
<group attrs="{'invisible':[('type', 'not in', ['in_refund', 'out_refund'])]}">
<separator string="Description" colspan="4"/>
<field name="refund_reason" nolabel="1"/>
<separator string="Original invoice" colspan="4"/>
<field name="origin_invoice_ids" nolabel="1">
<tree decoration-info="state == 'draft'"
decoration-muted="state == 'cancel'"
string="Original invoice">
<field name="partner_id" string="Customer"/>
<field name="date_invoice" string="Bill date"/>
<field name="date_due" string="Due date"/>
<field name="number" string="Number"/>
<field name="reference" string="Reference"/>
<field name="origin" string="Source"/>
<field name="amount_total_signed" string="Total"/>
<field name="residual_signed" string="Due"/>
<field name="state" string="Status"/>
</tree>
</field>
</group>
<group attrs="{'invisible':[('type', 'not in', ['in_invoice', 'out_invoice'])]}">
<separator string="Refund invoices" colspan="4"/>
<field name="refund_invoice_ids" nolabel="1">
<tree decoration-info="state == 'draft'"
decoration-muted="state == 'cancel'"
string="Refund invoices">
<field name="partner_id" string="Customer"/>
<field name="date_invoice" string="Bill date"/>
<field name="number" string="Number"/>
<field name="reference" string="Reference"/>
<field name="origin" string="Source"/>
<field name="refund_reason" string="Refund reason"/>
<field name="amount_total" string="Total"/>
<field name="state" string="Status"/>
</tree>
</field>
</group>
<page name="refunds"
string="Refunds"
attrs="{'invisible':[('type', 'not in', ['in_invoice', 'out_invoice'])]}"
>
<field name="refund_invoice_ids" nolabel="1">
<tree decoration-info="state == 'draft'"
decoration-muted="state == 'cancel'"
string="Refund invoices">
<field name="partner_id" string="Customer"/>
<field name="date_invoice" string="Bill date"/>
<field name="number" string="Number"/>
<field name="reference" string="Reference"/>
<field name="origin" string="Source"/>
<field name="refund_reason" string="Refund reason"/>
<field name="amount_total" string="Total"/>
<field name="state" string="Status"/>
</tree>
</field>
</page>
</notebook>
<xpath expr="//page[@name='other_info']//field[@name='origin']" position="after">
<field name="refund_invoice_id"
readonly="1"
attrs="{'invisible': [('refund_invoice_id', '=', False)]}"
/>
<field name="refund_reason"
readonly="1"
attrs="{'invisible': [('refund_reason', '=', False)]}"
/>
</xpath>
</field>
</record>

Expand All @@ -60,46 +50,36 @@
<field name="inherit_id" ref="account.invoice_supplier_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page name="refunds" string="Refunds">
<group attrs="{'invisible':[('type', 'not in', ['in_refund', 'out_refund'])]}">
<separator string="Description" colspan="4"/>
<field name="refund_reason" nolabel="1"/>
<separator string="Original invoice" colspan="4"/>
<field name="origin_invoice_ids" nolabel="1">
<tree decoration-info="state == 'draft'"
decoration-muted="state == 'cancel'"
string="Original invoice">
<field name="partner_id" string="Supplier"/>
<field name="date_invoice" string="Bill date"/>
<field name="date_due" string="Due date"/>
<field name="number" string="Number"/>
<field name="reference" string="Reference"/>
<field name="origin" string="Source"/>
<field name="amount_total_signed" string="Total"/>
<field name="residual_signed" string="Due"/>
<field name="state" string="Status"/>
</tree>
</field>
</group>
<group attrs="{'invisible':[('type', 'not in', ['in_invoice', 'out_invoice'])]}">
<separator string="Refund invoices" colspan="4"/>
<field name="refund_invoice_ids" nolabel="1">
<tree decoration-info="state == 'draft'"
decoration-muted="state == 'cancel'"
string="Refund invoices">
<field name="partner_id" string="Supplier"/>
<field name="date_invoice" string="Bill date"/>
<field name="number" string="Number"/>
<field name="reference" string="Reference"/>
<field name="origin" string="Source"/>
<field name="refund_reason" string="Refund reason"/>
<field name="amount_total" string="Total"/>
<field name="state" string="Status"/>
</tree>
</field>
</group>
<page name="refunds"
string="Refunds"
attrs="{'invisible':[('type', 'not in', ['in_invoice', 'out_invoice'])]}"
>
<field name="refund_invoice_ids" nolabel="1">
<tree decoration-info="state == 'draft'"
decoration-muted="state == 'cancel'"
string="Refund invoices">
<field name="partner_id" string="Supplier"/>
<field name="date_invoice" string="Bill date"/>
<field name="number" string="Number"/>
<field name="reference" string="Reference"/>
<field name="origin" string="Source"/>
<field name="refund_reason" string="Refund reason"/>
<field name="amount_total" string="Total"/>
<field name="state" string="Status"/>
</tree>
</field>
</page>
</notebook>
<xpath expr="//page[@name='other_info']//field[@name='name']" position="after">
<field name="refund_invoice_id"
readonly="1"
attrs="{'invisible': [('refund_invoice_id', '=', False)]}"
/>
<field name="refund_reason"
readonly="1"
attrs="{'invisible': [('refund_reason', '=', False)]}"
/>
</xpath>
</field>
</record>

Expand Down

0 comments on commit cdbf593

Please sign in to comment.