# HG changeset patch
# User Damien Habets <damien.habets@xcg-consulting.fr>
# Date 1646401725 -3600
#      Fri Mar 04 14:48:45 2022 +0100
# Branch 11.0
# Node ID 572008a0c0392999f546531e57fcb93185dc49f2
# Parent  938072cb90cca2b36e193dba28ba00d80d9e80a6
Add invoice_origin in account moves and lines & invoices

diff --git a/.hgconf b/.hgconf
--- a/.hgconf
+++ b/.hgconf
@@ -25,6 +25,11 @@
 layout = ../../../github.com/xcgd/reporting-engine
 track = d79115deade2674ac2f87b9b6cacdc8c1afaefd0
 
+[OCA/account-invoicing]
+pulluri = https://github.com/OCA/account-invoicing.git
+layout = ../../../oca/account-invoicing
+track = 277b001e983e68e268fa9f4a3db4becf4fab0470
+
 [account_export]
 pulluri = https://orus.io/xcg/odoo-modules/account_export
 layout = ../account_export
diff --git a/NEWS.rst b/NEWS.rst
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -1,3 +1,9 @@
+11.0.1.3.0
+==========
+
+* Account invoices, moves, and move lines: Invoice origin.
+  Filled from the original invoice/refund.
+
 11.0.1.2.0
 ==========
 
diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -13,7 +13,8 @@
 
     * Account consultation.
     * Accounting entries: Add a balance which is simply debit - credit.
-    * Invoices: "Paid amount" field.
+    * Invoices: "Paid amount", "Invoice origin" fields.
+    * Moves and move lines: "Invoice origin" field.
 
 
 Configuration
diff --git a/__manifest__.py b/__manifest__.py
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -51,13 +51,14 @@
     * Parser (``parser``): ``account_report.reports.account_statement.Parser``.
       Optional; provides ``debit_sum``, ``credit_sum``, ``balance_sum``.
 """,
-    "version": "11.0.1.2.0",
+    "version": "11.0.1.3.0",
     "category": "Accounting",
     "author": "XCG Consulting",
     "website": "http://odoo.consulting/",
     "depends": [
         "base",
         "account",
+        "account_invoice_refund_link",
         "account_invoicing",
         "account_payment_split",
         "account_period",
@@ -71,6 +72,8 @@
         "menu.xml",
         "wizards/account_consultation.xml",
         "views/account_account_type.xml",
+        "views/account_invoice.xml",
+        "views/account_move.xml",
         "views/account_move_line.xml",
         "views/account_report.xml",
     ],
diff --git a/models/__init__.py b/models/__init__.py
--- a/models/__init__.py
+++ b/models/__init__.py
@@ -1,1 +1,1 @@
-from . import account_invoice, account_move_line  # noqa: F401
+from . import account_invoice, account_move, account_move_line  # noqa: F401
diff --git a/models/account_invoice.py b/models/account_invoice.py
--- a/models/account_invoice.py
+++ b/models/account_invoice.py
@@ -28,6 +28,13 @@
 
     _inherit = "account.invoice"
 
+    invoice_origin = fields.Char(
+        string="Origin Object",
+        readonly=True,
+        index=True,
+        help="The invoice or refund that generated this invoice.",
+    )
+
     @api.one
     def _get_paid_amount(self):
         self.paid_amount = (
diff --git a/models/account_move.py b/models/account_move.py
new file mode 100644
--- /dev/null
+++ b/models/account_move.py
@@ -0,0 +1,63 @@
+##############################################################################
+#
+#    Accounting reports, for Odoo
+#    Copyright (C) 2022 XCG Consulting <http://odoo.consulting>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from odoo import api, fields, models
+
+
+class AccountingMove(models.Model):
+    """Add invoice origin, the object that generated this account move.
+    This field is copied in account move lines.
+    """
+
+    _inherit = "account.move"
+
+    invoice_origin = fields.Char(
+        string="Invoice origin",
+        readonly=True,
+        index=True,
+        help="The invoice or refund that generated this account move.",
+    )
+
+    @api.multi
+    def write(self, vals):
+        """Override to fill the invoice_origin field in invoices, moves, and
+        move lines."""
+        invoice = self.env.context.get("invoice")
+        if "name" in vals and invoice:
+            invoice_origin = vals["name"]
+            if (
+                invoice.type in ["in_refund", "out_refund"]
+                and invoice.refund_invoice_id
+            ):
+                # invoice_origin refers to the invoice that created the refund
+                invoice_origin = invoice.refund_invoice_id.number
+
+            # Fill invoice_origin. 3 objects.
+            vals["invoice_origin"] = invoice_origin
+            self.env.cr.execute(
+                "UPDATE account_invoice SET invoice_origin=%s WHERE id=%s",
+                (invoice_origin, invoice.id),
+            )
+            self.env.cr.execute(
+                "UPDATE account_move_line SET invoice_origin=%s "
+                "WHERE move_id IN %s",
+                (invoice_origin, tuple(self.ids)),
+            )
+        return super(AccountingMove, self).write(vals)
diff --git a/models/account_move_line.py b/models/account_move_line.py
--- a/models/account_move_line.py
+++ b/models/account_move_line.py
@@ -29,6 +29,13 @@
 
     _inherit = "account.move.line"
 
+    invoice_origin = fields.Char(
+        string="Invoice origin",
+        readonly=True,
+        index=True,
+        help="The object that generated this account move line.",
+    )
+
     @api.depends("debit", "credit")
     @api.one
     def _get_reporting_balance(self):
diff --git a/tests/test_account_report.py b/tests/test_account_report.py
--- a/tests/test_account_report.py
+++ b/tests/test_account_report.py
@@ -99,7 +99,7 @@
         """Check the "Paid amount" field we have added into invoices.
         """
 
-        # Create an inovice.
+        # Create an invoice.
         client = self._createPartner()
         invoice = self._makeInvoice(client)
         self.assertEqual(invoice.paid_amount, 0.0)  # No payments so far.
@@ -127,6 +127,57 @@
         self.assertEqual(invoice.paid_amount, AMOUNT)
         self.assertEqual(invoice.state, "paid")
 
+    def test_invoice_origin(self):
+        """Test that the 'Invoice Origin' field is filled correctly.
+        """
+        # Create an invoice.
+        client = self._createPartner()
+        invoice = self._makeInvoice(client)
+        invoice.action_move_create()
+        self.assertTrue(invoice.number)
+        self.assertEqual(invoice.invoice_origin, invoice.number)
+        self.assertEqual(invoice.move_id.invoice_origin, invoice.number)
+        self.assertEqual(
+            invoice.move_id.line_ids[0].invoice_origin, invoice.number
+        )
+
+        # Create a refund that has a refund_invoice_id
+        client = self._createPartner()
+        invoice = self._makeInvoice(client)
+        refund = self.env["account.invoice"].create(
+            {
+                "type": "in_refund",
+                "partner_id": invoice.partner_id.id,
+                "journal_id": invoice.journal_id.id,
+                "invoice_line_ids": [
+                    (
+                        0,
+                        0,
+                        {
+                            "account_id": self.credit_account.id,
+                            "name": "TEST-INVLINE",
+                            "price_unit": AMOUNT,
+                            "product_id": self.product.id,
+                            "quantity": 1.0,
+                        },
+                    )
+                ],
+            }
+        )
+        refund.refund_invoice_id = invoice
+        invoice.action_invoice_open()
+        self.assertTrue(invoice.move_id)
+        self.assertEqual(invoice.state, "open")
+        refund.action_invoice_open()
+        self.assertTrue(refund.number)
+        self.assertTrue(refund.move_id)
+        self.assertEqual(refund.invoice_origin, invoice.number)
+        self.assertEqual(refund.invoice_origin, invoice.move_id.name)
+        self.assertEqual(refund.move_id.invoice_origin, invoice.number)
+        self.assertEqual(
+            refund.move_id.line_ids[0].invoice_origin, invoice.number
+        )
+
     def _consult_account(self, account, **kwargs):
         """Consult the specified account; return extracted accounting entries.
 
diff --git a/views/account_invoice.xml b/views/account_invoice.xml
new file mode 100644
--- /dev/null
+++ b/views/account_invoice.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+    <record id="account_report_view_invoice_form" model="ir.ui.view">
+        <field name="name">account_report_view_invoice_form</field>
+        <field name="model">account.invoice</field>
+        <field name="inherit_id" ref="account.invoice_form"/>
+        <field name="arch" type="xml">
+
+            <xpath expr="//field[@name='user_id']" position="before">
+                <field name="invoice_origin" attrs="{'invisible': [('invoice_origin', '=', False)]}"/>
+            </xpath>
+
+        </field>
+    </record>
+
+</odoo>
diff --git a/views/account_move.xml b/views/account_move.xml
new file mode 100644
--- /dev/null
+++ b/views/account_move.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+    <record id="account_report_view_move_form" model="ir.ui.view">
+        <field name="name">account_report.view_move_form</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="account.view_move_form"/>
+        <field name="arch" type="xml">
+
+           <xpath expr="//field[@name='journal_id']" position="after">
+               <field name="invoice_origin" attrs="{'invisible': [('invoice_origin', '=', False)]}"/>
+           </xpath>
+
+        </field>
+    </record>
+
+</odoo>
diff --git a/views/account_move_line.xml b/views/account_move_line.xml
--- a/views/account_move_line.xml
+++ b/views/account_move_line.xml
@@ -23,6 +23,7 @@
                     <field name="partner_supplier_code" />
                     <field name="account_id" />
                     <field name="name" />
+                    <field name="invoice_origin" />
                     <field name="full_reconcile_id" />
                     <field name="date_reconcile" />
                     <field name="debit" sum="Total" />