From 3a4affe61e02d8a42674c32f602bcd24dd291c14 Mon Sep 17 00:00:00 2001
From: amcor
Date: Tue, 28 May 2019 17:10:15 +0200
Subject: [PATCH 01/24] [FIX] no plural in module name
---
project_purchase_link/README.rst | 29 ++++++
project_purchase_link/__init__.py | 4 +
project_purchase_link/__manifest__.py | 21 +++++
project_purchase_link/i18n/es.po | 68 ++++++++++++++
project_purchase_link/models/__init__.py | 4 +
.../models/project_project.py | 91 +++++++++++++++++++
project_purchase_link/readme/CONTRIBUTORS.rst | 2 +
project_purchase_link/readme/DESCRIPTION.rst | 2 +
project_purchase_link/tests/__init__.py | 4 +
.../tests/test_project_purchase_utilities.py | 70 ++++++++++++++
.../views/project_project_view.xml | 23 +++++
11 files changed, 318 insertions(+)
create mode 100644 project_purchase_link/README.rst
create mode 100644 project_purchase_link/__init__.py
create mode 100644 project_purchase_link/__manifest__.py
create mode 100644 project_purchase_link/i18n/es.po
create mode 100644 project_purchase_link/models/__init__.py
create mode 100644 project_purchase_link/models/project_project.py
create mode 100644 project_purchase_link/readme/CONTRIBUTORS.rst
create mode 100644 project_purchase_link/readme/DESCRIPTION.rst
create mode 100644 project_purchase_link/tests/__init__.py
create mode 100644 project_purchase_link/tests/test_project_purchase_utilities.py
create mode 100644 project_purchase_link/views/project_project_view.xml
diff --git a/project_purchase_link/README.rst b/project_purchase_link/README.rst
new file mode 100644
index 0000000000..fafa62a7dd
--- /dev/null
+++ b/project_purchase_link/README.rst
@@ -0,0 +1,29 @@
+.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
+ :target: https://www.gnu.org/licenses/agpl
+ :alt: License: AGPL-3
+
+==========================
+Project Purchase Utilities
+==========================
+
+With this module you can access to purchase orders and invoices related to the
+project.
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues
+`_. In case of trouble, please
+check there if your issue has already been reported. If you spotted it first,
+help us smash it by providing detailed and welcomed feedback.
+
+Do not contact contributors directly about support or help with technical issues.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Oihane Crucelaegui
+* Ana Juaristi
diff --git a/project_purchase_link/__init__.py b/project_purchase_link/__init__.py
new file mode 100644
index 0000000000..4209851d55
--- /dev/null
+++ b/project_purchase_link/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+
+from . import models
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
new file mode 100644
index 0000000000..1b47c32fe8
--- /dev/null
+++ b/project_purchase_link/__manifest__.py
@@ -0,0 +1,21 @@
+# Copyright 2018 Gontzal Gomez - AvanzOSC
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+
+{
+ "name": "Project Purchase Utilities",
+ "version": "12.0.1.1.0",
+ "license": "AGPL-3",
+ "depends": [
+ "project",
+ "purchase",
+ "hr_timesheet",
+ ],
+ "author": "AvanzOSC, "
+ 'Odoo Community Association (OCA)',
+ "website": "http://github.com/OCA/project.git",
+ "category": "Project",
+ "data": [
+ "views/project_project_view.xml",
+ ],
+ "installable": True,
+}
diff --git a/project_purchase_link/i18n/es.po b/project_purchase_link/i18n/es.po
new file mode 100644
index 0000000000..dd906fc329
--- /dev/null
+++ b/project_purchase_link/i18n/es.po
@@ -0,0 +1,68 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase_utilities
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 11.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-01-25 08:47+0000\n"
+"PO-Revision-Date: 2019-01-25 08:47+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: project_purchase_utilities
+#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_count
+#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_line_count
+msgid "# Purchase"
+msgstr "N.º de compras"
+
+#. module: project_purchase_utilities
+#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_invoice_count
+#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_invoice_line_count
+msgid "# Purchase Invoice"
+msgstr "N.º de facturas de compra"
+
+#. module: project_purchase_utilities
+#: model:ir.model,name:project_purchase_utilities.model_project_project
+msgid "Project"
+msgstr "Proyecto"
+
+#. module: project_purchase_utilities
+#: code:addons/project_purchase_utilities/models/project_project.py:86
+#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
+#, python-format
+msgid "Purchase Invoice Lines"
+msgstr "Líneas de factura de compra"
+
+#. module: project_purchase_utilities
+#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
+msgid "Purchase Invoices"
+msgstr "Facturas de compra"
+
+#. module: project_purchase_utilities
+#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
+msgid "Purchase Lines"
+msgstr "Líneas de compra"
+
+#. module: project_purchase_utilities
+#: code:addons/project_purchase_utilities/models/project_project.py:46
+#, python-format
+msgid "Purchase Order"
+msgstr "Pedido de compra"
+
+#. module: project_purchase_utilities
+#: code:addons/project_purchase_utilities/models/project_project.py:59
+#, python-format
+msgid "Purchase Order Lines"
+msgstr "Líneas de pedido de compra"
+
+#. module: project_purchase_utilities
+#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
+msgid "Purchases"
+msgstr "Compras"
+
diff --git a/project_purchase_link/models/__init__.py b/project_purchase_link/models/__init__.py
new file mode 100644
index 0000000000..6fe88855d5
--- /dev/null
+++ b/project_purchase_link/models/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+
+from . import project_project
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
new file mode 100644
index 0000000000..0e7404199f
--- /dev/null
+++ b/project_purchase_link/models/project_project.py
@@ -0,0 +1,91 @@
+# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+
+from odoo.tools.safe_eval import safe_eval
+from odoo import _, api, fields, models
+from odoo.osv import expression
+
+
+class ProjectProject(models.Model):
+ _inherit = 'project.project'
+
+ purchase_count = fields.Integer(
+ compute='_compute_purchase_count', string='# Purchase')
+ purchase_line_count = fields.Integer(
+ compute='_compute_purchase_count', string='# Purchase')
+ purchase_invoice_count = fields.Integer(
+ compute='_compute_purchase_invoice_count', string='# Purchase Invoice')
+ purchase_invoice_line_count = fields.Integer(
+ compute='_compute_purchase_invoice_count', string='# Purchase Invoice')
+
+ @api.multi
+ def _compute_purchase_count(self):
+ for project in self:
+ purchase_lines = self.env['purchase.order.line'].search([
+ ('account_analytic_id', '=', project.analytic_account_id.id)])
+ project.purchase_count = len(purchase_lines.mapped('order_id'))
+ project.purchase_line_count = len(purchase_lines)
+
+ @api.multi
+ def _compute_purchase_invoice_count(self):
+ for project in self:
+ invoice_lines = self.env['account.invoice.line'].search([
+ ('account_analytic_id', '=', project.analytic_account_id.id)])
+ project.purchase_invoice_count = len(
+ invoice_lines.mapped('invoice_id'))
+ project.purchase_invoice_line_count = len(invoice_lines)
+
+ @api.multi
+ def button_open_purchase_order(self):
+ self.ensure_one()
+ purchase_lines = self.env['purchase.order.line'].search([
+ ('account_analytic_id', 'in',
+ self.mapped('analytic_account_id').ids)])
+ domain = [('id', 'in', purchase_lines.mapped('order_id').ids)]
+ return {
+ 'name': _('Purchase Order'),
+ 'domain': domain,
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'tree,form',
+ 'res_model': 'purchase.order',
+ }
+
+ @api.multi
+ def button_open_purchase_order_line(self):
+ self.ensure_one()
+ domain = [('account_analytic_id', 'in',
+ self.mapped('analytic_account_id').ids)]
+ return {
+ 'name': _('Purchase Order Lines'),
+ 'domain': domain,
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'tree,form',
+ 'res_model': 'purchase.order.line',
+ }
+
+ @api.multi
+ def button_open_purchase_invoice(self):
+ self.ensure_one()
+ action = self.env.ref('purchase.action_invoice_pending')
+ action_dict = action.read()[0] if action else {}
+ lines = self.env['account.invoice.line'].search([
+ ('account_analytic_id', 'in',
+ self.mapped('analytic_account_id').ids)])
+ domain = expression.AND([
+ [('id', 'in', lines.mapped('invoice_id').ids)],
+ safe_eval(action.domain or '[]')])
+ action_dict.update({'domain': domain})
+ return action_dict
+
+ @api.multi
+ def button_open_purchase_invoice_line(self):
+ self.ensure_one()
+ domain = [('account_analytic_id', 'in',
+ self.mapped('analytic_account_id').ids)]
+ return {
+ 'name': _('Purchase Invoice Lines'),
+ 'domain': domain,
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'tree,form',
+ 'res_model': 'account.invoice.line',
+ }
diff --git a/project_purchase_link/readme/CONTRIBUTORS.rst b/project_purchase_link/readme/CONTRIBUTORS.rst
new file mode 100644
index 0000000000..02b991ddf9
--- /dev/null
+++ b/project_purchase_link/readme/CONTRIBUTORS.rst
@@ -0,0 +1,2 @@
+* Oihane Crucelaegui
+* Ana Juaristi
diff --git a/project_purchase_link/readme/DESCRIPTION.rst b/project_purchase_link/readme/DESCRIPTION.rst
new file mode 100644
index 0000000000..81a04d1c61
--- /dev/null
+++ b/project_purchase_link/readme/DESCRIPTION.rst
@@ -0,0 +1,2 @@
+With this module you can access to purchase orders and invoices related to the
+project.
diff --git a/project_purchase_link/tests/__init__.py b/project_purchase_link/tests/__init__.py
new file mode 100644
index 0000000000..b0c7c9201b
--- /dev/null
+++ b/project_purchase_link/tests/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+
+from . import test_project_purchase_utilities
diff --git a/project_purchase_link/tests/test_project_purchase_utilities.py b/project_purchase_link/tests/test_project_purchase_utilities.py
new file mode 100644
index 0000000000..720701a56e
--- /dev/null
+++ b/project_purchase_link/tests/test_project_purchase_utilities.py
@@ -0,0 +1,70 @@
+# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+
+from odoo.tools.safe_eval import safe_eval
+from odoo.tests import common
+from odoo.osv import expression
+
+
+class TestProjectPurchaseUtilities(common.SavepointCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestProjectPurchaseUtilities, cls).setUpClass()
+ cls.project_model = cls.env['project.project']
+ cls.project = cls.project_model.create({
+ 'name': 'Test Project',
+ })
+ cls.purchase_model = cls.env['purchase.order']
+ cls.purchase = cls.purchase_model.search([
+ ('state', 'in', ('draft', 'sent')),
+ ], limit=1)
+ cls.invoice_model = cls.env['account.invoice']
+
+ def test_project_purchase(self):
+ self.assertTrue(self.purchase)
+ self.purchase.write({
+ 'invoice_status': 'to invoice',
+ })
+ self.assertFalse(self.project.purchase_count)
+ self.assertFalse(self.project.purchase_line_count)
+ self.assertFalse(self.project.purchase_invoice_count)
+ self.assertFalse(self.project.purchase_invoice_line_count)
+ self.purchase.order_line[:1].write({
+ 'account_analytic_id': self.project.analytic_account_id.id,
+ })
+ self.project.invalidate_cache()
+ self.assertEquals(self.project.purchase_count, 1)
+ self.assertEquals(self.project.purchase_line_count, 1)
+ self.assertFalse(self.project.purchase_invoice_count)
+ self.assertFalse(self.project.purchase_invoice_line_count)
+ self.purchase.button_confirm()
+ invoice = self.invoice_model.create({
+ 'partner_id': self.purchase.partner_id.id,
+ 'purchase_id': self.purchase.id,
+ 'type': 'in_invoice',
+ })
+ invoice.purchase_order_change()
+ self.project.invalidate_cache()
+ self.assertEquals(self.project.purchase_invoice_count, 1)
+ self.assertEquals(self.project.purchase_invoice_line_count, 1)
+ purchase_domain = [
+ ('account_analytic_id', 'in',
+ self.project.mapped('analytic_account_id').ids)]
+ purchase_lines = self.env['purchase.order.line'].search(
+ purchase_domain)
+ order_domain = [('id', 'in', purchase_lines.mapped('order_id').ids)]
+ purchase_dict = self.project.button_open_purchase_order()
+ self.assertEquals(purchase_dict.get('domain'), order_domain)
+ purchase_line_dict = self.project.button_open_purchase_order_line()
+ self.assertEquals(
+ purchase_line_dict.get('domain'), purchase_domain)
+ invoice_lines = self.env['account.invoice.line'].search(
+ purchase_domain)
+ invoice_action = self.browse_ref('purchase.action_invoice_pending')
+ invoice_domain = expression.AND([
+ [('id', 'in', invoice_lines.mapped('invoice_id').ids)],
+ safe_eval(invoice_action.domain or '[]')])
+ invoice_dict = self.project.button_open_purchase_invoice()
+ self.assertEquals(invoice_dict.get('domain'), invoice_domain)
+ invoice_line_dict = self.project.button_open_purchase_invoice_line()
+ self.assertEquals(invoice_line_dict.get('domain'), purchase_domain)
diff --git a/project_purchase_link/views/project_project_view.xml b/project_purchase_link/views/project_project_view.xml
new file mode 100644
index 0000000000..48df6ea15a
--- /dev/null
+++ b/project_purchase_link/views/project_project_view.xml
@@ -0,0 +1,23 @@
+
+
+
+ project.project
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From c398d68fd332fd6cd760cb0a5877ee82bf6ffcde Mon Sep 17 00:00:00 2001
From: amcor
Date: Thu, 30 May 2019 17:22:09 +0200
Subject: [PATCH 02/24] [IMP] change purchase/invoice lines count to price
sutotal
---
project_purchase_link/__manifest__.py | 4 +-
.../models/project_project.py | 48 ++++++++++++-------
project_purchase_link/readme/CONTRIBUTORS.rst | 2 +
project_purchase_link/tests/__init__.py | 2 +-
...ities.py => test_project_purchase_link.py} | 13 +++--
.../views/project_project_view.xml | 4 +-
6 files changed, 46 insertions(+), 27 deletions(-)
rename project_purchase_link/tests/{test_project_purchase_utilities.py => test_project_purchase_link.py} (87%)
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index 1b47c32fe8..07981d95c6 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -2,8 +2,8 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
- "name": "Project Purchase Utilities",
- "version": "12.0.1.1.0",
+ "name": "Project Purchase Link",
+ "version": "12.0.1.1.1",
"license": "AGPL-3",
"depends": [
"project",
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 0e7404199f..54d3b066cb 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -10,30 +10,44 @@ class ProjectProject(models.Model):
_inherit = 'project.project'
purchase_count = fields.Integer(
- compute='_compute_purchase_count', string='# Purchase')
- purchase_line_count = fields.Integer(
- compute='_compute_purchase_count', string='# Purchase')
+ compute='_compute_purchase_info', string='# Purchase')
+ purchase_line_total = fields.Integer(
+ compute='_compute_purchase_info', string='Purchase Total')
purchase_invoice_count = fields.Integer(
- compute='_compute_purchase_invoice_count', string='# Purchase Invoice')
- purchase_invoice_line_count = fields.Integer(
- compute='_compute_purchase_invoice_count', string='# Purchase Invoice')
+ compute='_compute_purchase_invoice_info', string='# Purchase Invoice')
+ purchase_invoice_line_total = fields.Float(
+ compute='_compute_purchase_invoice_info',
+ string='Purchase Invoice Total')
@api.multi
- def _compute_purchase_count(self):
+ def _compute_purchase_info(self):
for project in self:
- purchase_lines = self.env['purchase.order.line'].search([
- ('account_analytic_id', '=', project.analytic_account_id.id)])
- project.purchase_count = len(purchase_lines.mapped('order_id'))
- project.purchase_line_count = len(purchase_lines)
+ groups = self.env['purchase.order.line'].read_group(
+ [('account_analytic_id', '=', project.analytic_account_id.id),
+ ('order_id.state', '!=', 'cancel')],
+ ['price_subtotal'],
+ ['order_id'])
+ purchase_line_total = 0
+ for group in groups:
+ purchase_line_total += group['price_subtotal']
+
+ project.purchase_count = len(groups)
+ project.purchase_line_total = purchase_line_total
@api.multi
- def _compute_purchase_invoice_count(self):
+ def _compute_purchase_invoice_info(self):
for project in self:
- invoice_lines = self.env['account.invoice.line'].search([
- ('account_analytic_id', '=', project.analytic_account_id.id)])
- project.purchase_invoice_count = len(
- invoice_lines.mapped('invoice_id'))
- project.purchase_invoice_line_count = len(invoice_lines)
+ groups = self.env['account.invoice.line'].read_group(
+ [('account_analytic_id', '=', project.analytic_account_id.id),
+ ('invoice_id.state', '!=', 'cancel')],
+ ['price_subtotal'],
+ ['invoice_id'])
+ purchase_invoice_line_total = 0
+ for group in groups:
+ purchase_invoice_line_total += group['price_subtotal']
+
+ project.purchase_invoice_count = len(groups)
+ project.purchase_invoice_line_total = purchase_invoice_line_total
@api.multi
def button_open_purchase_order(self):
diff --git a/project_purchase_link/readme/CONTRIBUTORS.rst b/project_purchase_link/readme/CONTRIBUTORS.rst
index 02b991ddf9..e3aab202d7 100644
--- a/project_purchase_link/readme/CONTRIBUTORS.rst
+++ b/project_purchase_link/readme/CONTRIBUTORS.rst
@@ -1,2 +1,4 @@
* Oihane Crucelaegui
* Ana Juaristi
+* Alberto Martín Cortada
+
diff --git a/project_purchase_link/tests/__init__.py b/project_purchase_link/tests/__init__.py
index b0c7c9201b..f60408dbde 100644
--- a/project_purchase_link/tests/__init__.py
+++ b/project_purchase_link/tests/__init__.py
@@ -1,4 +1,4 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-from . import test_project_purchase_utilities
+from . import test_project_purchase_link
diff --git a/project_purchase_link/tests/test_project_purchase_utilities.py b/project_purchase_link/tests/test_project_purchase_link.py
similarity index 87%
rename from project_purchase_link/tests/test_project_purchase_utilities.py
rename to project_purchase_link/tests/test_project_purchase_link.py
index 720701a56e..f10ce67e01 100644
--- a/project_purchase_link/tests/test_project_purchase_utilities.py
+++ b/project_purchase_link/tests/test_project_purchase_link.py
@@ -26,17 +26,20 @@ def test_project_purchase(self):
'invoice_status': 'to invoice',
})
self.assertFalse(self.project.purchase_count)
- self.assertFalse(self.project.purchase_line_count)
+ self.assertFalse(self.project.purchase_line_total)
self.assertFalse(self.project.purchase_invoice_count)
- self.assertFalse(self.project.purchase_invoice_line_count)
+ self.assertFalse(self.project.purchase_invoice_line_total)
self.purchase.order_line[:1].write({
'account_analytic_id': self.project.analytic_account_id.id,
+ 'price_unit': 50,
+ 'product_qty': 4,
+ 'qty_received': 4,
})
self.project.invalidate_cache()
self.assertEquals(self.project.purchase_count, 1)
- self.assertEquals(self.project.purchase_line_count, 1)
+ self.assertEquals(self.project.purchase_line_total, 200)
self.assertFalse(self.project.purchase_invoice_count)
- self.assertFalse(self.project.purchase_invoice_line_count)
+ self.assertFalse(self.project.purchase_invoice_line_total)
self.purchase.button_confirm()
invoice = self.invoice_model.create({
'partner_id': self.purchase.partner_id.id,
@@ -46,7 +49,7 @@ def test_project_purchase(self):
invoice.purchase_order_change()
self.project.invalidate_cache()
self.assertEquals(self.project.purchase_invoice_count, 1)
- self.assertEquals(self.project.purchase_invoice_line_count, 1)
+ self.assertEquals(self.project.purchase_invoice_line_total, 200)
purchase_domain = [
('account_analytic_id', 'in',
self.project.mapped('analytic_account_id').ids)]
diff --git a/project_purchase_link/views/project_project_view.xml b/project_purchase_link/views/project_project_view.xml
index 48df6ea15a..44db57bd92 100644
--- a/project_purchase_link/views/project_project_view.xml
+++ b/project_purchase_link/views/project_project_view.xml
@@ -9,13 +9,13 @@
-
+
-
+
From 9ed8336b09f5638d5ccaa77f4c57393a96e46e91 Mon Sep 17 00:00:00 2001
From: amcor
Date: Tue, 30 Jul 2019 08:21:33 +0200
Subject: [PATCH 03/24] [FIX] reset version code
---
project_purchase_link/README.rst | 70 ++-
project_purchase_link/__manifest__.py | 2 +-
project_purchase_link/i18n/es.po | 59 +--
.../i18n/project_purchase_link.pot | 70 +++
.../static/description/index.html | 422 ++++++++++++++++++
5 files changed, 586 insertions(+), 37 deletions(-)
create mode 100644 project_purchase_link/i18n/project_purchase_link.pot
create mode 100644 project_purchase_link/static/description/index.html
diff --git a/project_purchase_link/README.rst b/project_purchase_link/README.rst
index fafa62a7dd..cd274c5685 100644
--- a/project_purchase_link/README.rst
+++ b/project_purchase_link/README.rst
@@ -1,29 +1,77 @@
-.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
- :target: https://www.gnu.org/licenses/agpl
- :alt: License: AGPL-3
+=====================
+Project Purchase Link
+=====================
-==========================
-Project Purchase Utilities
-==========================
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Beta
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproject-lightgray.png?logo=github
+ :target: https://github.com/OCA/project/tree/12.0/project_purchase_link
+ :alt: OCA/project
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/project-12-0/project-12-0-project_purchase_link
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/140/12.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
With this module you can access to purchase orders and invoices related to the
project.
+**Table of contents**
+
+.. contents::
+ :local:
+
Bug Tracker
===========
-Bugs are tracked on `GitHub Issues
-`_. In case of trouble, please
-check there if your issue has already been reported. If you spotted it first,
-help us smash it by providing detailed and welcomed feedback.
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
+Authors
+~~~~~~~
+
+* AvanzOSC
+
Contributors
-------------
+~~~~~~~~~~~~
* Oihane Crucelaegui
* Ana Juaristi
+* Alberto Martín Cortada
+
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+This module is part of the `OCA/project `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index 07981d95c6..d48155c3d9 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Project Purchase Link",
- "version": "12.0.1.1.1",
+ "version": "12.0.1.0.0",
"license": "AGPL-3",
"depends": [
"project",
diff --git a/project_purchase_link/i18n/es.po b/project_purchase_link/i18n/es.po
index dd906fc329..e956ed63d2 100644
--- a/project_purchase_link/i18n/es.po
+++ b/project_purchase_link/i18n/es.po
@@ -1,6 +1,6 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
-# * project_purchase_utilities
+# * project_purchase_utilities
#
msgid ""
msgstr ""
@@ -10,59 +10,68 @@ msgstr ""
"PO-Revision-Date: 2019-01-25 08:47+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
+"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
-#. module: project_purchase_utilities
-#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_count
-#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_line_count
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_count
msgid "# Purchase"
msgstr "N.º de compras"
-#. module: project_purchase_utilities
-#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_invoice_count
-#: model:ir.model.fields,field_description:project_purchase_utilities.field_project_project_purchase_invoice_line_count
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_count
msgid "# Purchase Invoice"
msgstr "N.º de facturas de compra"
-#. module: project_purchase_utilities
-#: model:ir.model,name:project_purchase_utilities.model_project_project
+#. module: project_purchase_link
+#: model:ir.model,name:project_purchase_link.model_project_project
msgid "Project"
msgstr "Proyecto"
-#. module: project_purchase_utilities
-#: code:addons/project_purchase_utilities/models/project_project.py:86
-#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:100
#, python-format
msgid "Purchase Invoice Lines"
msgstr "Líneas de factura de compra"
-#. module: project_purchase_utilities
-#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
-msgid "Purchase Invoices"
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+#, fuzzy
+msgid "Purchase Invoice Total"
msgstr "Facturas de compra"
-#. module: project_purchase_utilities
-#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
-msgid "Purchase Lines"
-msgstr "Líneas de compra"
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoices"
+msgstr "Facturas de compra"
-#. module: project_purchase_utilities
-#: code:addons/project_purchase_utilities/models/project_project.py:46
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:60
#, python-format
msgid "Purchase Order"
msgstr "Pedido de compra"
-#. module: project_purchase_utilities
-#: code:addons/project_purchase_utilities/models/project_project.py:59
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:73
#, python-format
msgid "Purchase Order Lines"
msgstr "Líneas de pedido de compra"
-#. module: project_purchase_utilities
-#: model:ir.ui.view,arch_db:project_purchase_utilities.project_project_view_form
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+#, fuzzy
+msgid "Purchase Total"
+msgstr "Compras"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
msgid "Purchases"
msgstr "Compras"
+#~ msgid "Purchase Lines"
+#~ msgstr "Líneas de compra"
diff --git a/project_purchase_link/i18n/project_purchase_link.pot b/project_purchase_link/i18n/project_purchase_link.pot
new file mode 100644
index 0000000000..741807b2bb
--- /dev/null
+++ b/project_purchase_link/i18n/project_purchase_link.pot
@@ -0,0 +1,70 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase_link
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_count
+msgid "# Purchase"
+msgstr ""
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_count
+msgid "# Purchase Invoice"
+msgstr ""
+
+#. module: project_purchase_link
+#: model:ir.model,name:project_purchase_link.model_project_project
+msgid "Project"
+msgstr ""
+
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:100
+#, python-format
+msgid "Purchase Invoice Lines"
+msgstr ""
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoice Total"
+msgstr ""
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoices"
+msgstr ""
+
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:60
+#, python-format
+msgid "Purchase Order"
+msgstr ""
+
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:73
+#, python-format
+msgid "Purchase Order Lines"
+msgstr ""
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Total"
+msgstr ""
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchases"
+msgstr ""
+
diff --git a/project_purchase_link/static/description/index.html b/project_purchase_link/static/description/index.html
new file mode 100644
index 0000000000..63ad4cfb76
--- /dev/null
+++ b/project_purchase_link/static/description/index.html
@@ -0,0 +1,422 @@
+
+
+
+
+
+
+Project Purchase Link
+
+
+
+
+
Project Purchase Link
+
+
+
+
With this module you can access to purchase orders and invoices related to the
+project.
+
Table of contents
+
+
+
+
Bugs are tracked on GitHub Issues .
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+feedback .
+
Do not contact contributors directly about support or help with technical issues.
+
+
+
+
+
+
+
+
This module is maintained by the OCA.
+
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
This module is part of the OCA/project project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
+
+
+
+
+
From 2eaa9b2e84a884d0878bc227dbc6d90c9e39c82c Mon Sep 17 00:00:00 2001
From: Tony Galmiche
Date: Sat, 23 May 2020 12:43:57 +0200
Subject: [PATCH 04/24] [MIG] project_purchase_link: Migration to 13.0
---
project_purchase_link/README.rst | 19 ++-
project_purchase_link/__manifest__.py | 15 +--
project_purchase_link/i18n/es.po | 8 +-
.../i18n/project_purchase_link.pot | 13 +-
project_purchase_link/i18n/sl.po | 76 +++++++++++
.../models/project_project.py | 120 +++++++++---------
project_purchase_link/readme/CONTRIBUTORS.rst | 1 -
project_purchase_link/readme/USAGE.rst | 4 +
.../static/description/icon.png | Bin 0 -> 9455 bytes
.../static/description/index.html | 35 +++--
.../tests/test_project_purchase_link.py | 92 +++++++-------
.../views/project_project_view.xml | 48 +++++--
12 files changed, 277 insertions(+), 154 deletions(-)
create mode 100644 project_purchase_link/i18n/sl.po
create mode 100644 project_purchase_link/readme/USAGE.rst
create mode 100644 project_purchase_link/static/description/icon.png
diff --git a/project_purchase_link/README.rst b/project_purchase_link/README.rst
index cd274c5685..d3efadcf36 100644
--- a/project_purchase_link/README.rst
+++ b/project_purchase_link/README.rst
@@ -14,13 +14,13 @@ Project Purchase Link
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproject-lightgray.png?logo=github
- :target: https://github.com/OCA/project/tree/12.0/project_purchase_link
+ :target: https://github.com/OCA/project/tree/13.0/project_purchase_link
:alt: OCA/project
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/project-12-0/project-12-0-project_purchase_link
+ :target: https://translation.odoo-community.org/projects/project-13-0/project-13-0-project_purchase_link
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/140/12.0
+ :target: https://runbot.odoo-community.org/runbot/140/13.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -33,13 +33,21 @@ project.
.. contents::
:local:
+Usage
+=====
+
+To use this module, you need to:
+
+#. Belong to the "Show Full Accounting Features" and "Analytic Accounting" groups.
+#. On the lines of purchase orders or invoices, indicate the analytical account associated with the project.
+
Bug Tracker
===========
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -58,7 +66,6 @@ Contributors
* Ana Juaristi
* Alberto Martín Cortada
-
Maintainers
~~~~~~~~~~~
@@ -72,6 +79,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-This module is part of the `OCA/project `_ project on GitHub.
+This module is part of the `OCA/project `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index d48155c3d9..54fff81d14 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -3,19 +3,12 @@
{
"name": "Project Purchase Link",
- "version": "12.0.1.0.0",
+ "version": "13.0.1.0.0",
"license": "AGPL-3",
- "depends": [
- "project",
- "purchase",
- "hr_timesheet",
- ],
- "author": "AvanzOSC, "
- 'Odoo Community Association (OCA)',
+ "depends": ["project", "purchase", "hr_timesheet"],
+ "author": "AvanzOSC, " "Odoo Community Association (OCA)",
"website": "http://github.com/OCA/project.git",
"category": "Project",
- "data": [
- "views/project_project_view.xml",
- ],
+ "data": ["views/project_project_view.xml"],
"installable": True,
}
diff --git a/project_purchase_link/i18n/es.po b/project_purchase_link/i18n/es.po
index e956ed63d2..a8c714efeb 100644
--- a/project_purchase_link/i18n/es.po
+++ b/project_purchase_link/i18n/es.po
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 11.0\n"
+"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-25 08:47+0000\n"
"PO-Revision-Date: 2019-01-25 08:47+0000\n"
@@ -32,7 +32,7 @@ msgid "Project"
msgstr "Proyecto"
#. module: project_purchase_link
-#: code:addons/project_purchase_link/models/project_project.py:100
+#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Invoice Lines"
msgstr "Líneas de factura de compra"
@@ -50,13 +50,13 @@ msgid "Purchase Invoices"
msgstr "Facturas de compra"
#. module: project_purchase_link
-#: code:addons/project_purchase_link/models/project_project.py:60
+#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order"
msgstr "Pedido de compra"
#. module: project_purchase_link
-#: code:addons/project_purchase_link/models/project_project.py:73
+#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order Lines"
msgstr "Líneas de pedido de compra"
diff --git a/project_purchase_link/i18n/project_purchase_link.pot b/project_purchase_link/i18n/project_purchase_link.pot
index 741807b2bb..991e1002dd 100644
--- a/project_purchase_link/i18n/project_purchase_link.pot
+++ b/project_purchase_link/i18n/project_purchase_link.pot
@@ -1,12 +1,12 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
-# * project_purchase_link
+# * project_purchase_link
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 12.0\n"
+"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"Last-Translator: <>\n"
+"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -29,7 +29,7 @@ msgid "Project"
msgstr ""
#. module: project_purchase_link
-#: code:addons/project_purchase_link/models/project_project.py:100
+#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Invoice Lines"
msgstr ""
@@ -46,13 +46,13 @@ msgid "Purchase Invoices"
msgstr ""
#. module: project_purchase_link
-#: code:addons/project_purchase_link/models/project_project.py:60
+#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order"
msgstr ""
#. module: project_purchase_link
-#: code:addons/project_purchase_link/models/project_project.py:73
+#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order Lines"
msgstr ""
@@ -67,4 +67,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
msgid "Purchases"
msgstr ""
-
diff --git a/project_purchase_link/i18n/sl.po b/project_purchase_link/i18n/sl.po
new file mode 100644
index 0000000000..45e30e8ecf
--- /dev/null
+++ b/project_purchase_link/i18n/sl.po
@@ -0,0 +1,76 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase_link
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2020-03-31 10:14+0000\n"
+"Last-Translator: Matjaz Mozetic \n"
+"Language-Team: none\n"
+"Language: sl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
+"%100==4 ? 2 : 3;\n"
+"X-Generator: Weblate 3.10\n"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_count
+msgid "# Purchase"
+msgstr "# nabava"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_count
+msgid "# Purchase Invoice"
+msgstr "# prejeti račun"
+
+#. module: project_purchase_link
+#: model:ir.model,name:project_purchase_link.model_project_project
+msgid "Project"
+msgstr ""
+
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Invoice Lines"
+msgstr "Postavke prejetega računa"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoice Total"
+msgstr "Prejeti račun skupaj"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoices"
+msgstr "Prejeti računi"
+
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Order"
+msgstr "Nabavni nalog"
+
+#. module: project_purchase_link
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Lines"
+msgstr "Postavke nabavnega naloga"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Total"
+msgstr "Skupaj nabava"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchases"
+msgstr "Nabave"
+
+#~ msgid "WBS element"
+#~ msgstr "Projektni člen"
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 54d3b066cb..8f492400a3 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -1,105 +1,107 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-from odoo.tools.safe_eval import safe_eval
-from odoo import _, api, fields, models
+from odoo import _, fields, models
from odoo.osv import expression
+from odoo.tools.safe_eval import safe_eval
class ProjectProject(models.Model):
- _inherit = 'project.project'
+ _inherit = "project.project"
purchase_count = fields.Integer(
- compute='_compute_purchase_info', string='# Purchase')
+ compute="_compute_purchase_info", string="# Purchase"
+ )
purchase_line_total = fields.Integer(
- compute='_compute_purchase_info', string='Purchase Total')
+ compute="_compute_purchase_info", string="Purchase Total"
+ )
purchase_invoice_count = fields.Integer(
- compute='_compute_purchase_invoice_info', string='# Purchase Invoice')
+ compute="_compute_purchase_invoice_info", string="# Purchase Invoice"
+ )
purchase_invoice_line_total = fields.Float(
- compute='_compute_purchase_invoice_info',
- string='Purchase Invoice Total')
+ compute="_compute_purchase_invoice_info", string="Purchase Invoice Total"
+ )
- @api.multi
def _compute_purchase_info(self):
for project in self:
- groups = self.env['purchase.order.line'].read_group(
- [('account_analytic_id', '=', project.analytic_account_id.id),
- ('order_id.state', '!=', 'cancel')],
- ['price_subtotal'],
- ['order_id'])
+ groups = self.env["purchase.order.line"].read_group(
+ [
+ ("account_analytic_id", "=", project.analytic_account_id.id),
+ ("order_id.state", "!=", "cancel"),
+ ],
+ ["price_subtotal"],
+ ["order_id"],
+ )
purchase_line_total = 0
for group in groups:
- purchase_line_total += group['price_subtotal']
-
+ purchase_line_total += group["price_subtotal"]
project.purchase_count = len(groups)
project.purchase_line_total = purchase_line_total
- @api.multi
def _compute_purchase_invoice_info(self):
for project in self:
- groups = self.env['account.invoice.line'].read_group(
- [('account_analytic_id', '=', project.analytic_account_id.id),
- ('invoice_id.state', '!=', 'cancel')],
- ['price_subtotal'],
- ['invoice_id'])
+ groups = self.env["account.move.line"].read_group(
+ [
+ ("analytic_account_id", "=", project.analytic_account_id.id),
+ ("move_id.state", "!=", "cancel"),
+ ],
+ ["price_subtotal"],
+ ["move_id"],
+ )
purchase_invoice_line_total = 0
for group in groups:
- purchase_invoice_line_total += group['price_subtotal']
-
+ purchase_invoice_line_total += group["price_subtotal"]
project.purchase_invoice_count = len(groups)
project.purchase_invoice_line_total = purchase_invoice_line_total
- @api.multi
def button_open_purchase_order(self):
self.ensure_one()
- purchase_lines = self.env['purchase.order.line'].search([
- ('account_analytic_id', 'in',
- self.mapped('analytic_account_id').ids)])
- domain = [('id', 'in', purchase_lines.mapped('order_id').ids)]
+ purchase_lines = self.env["purchase.order.line"].search(
+ [("account_analytic_id", "in", self.mapped("analytic_account_id").ids)]
+ )
+ domain = [("id", "in", purchase_lines.mapped("order_id").ids)]
return {
- 'name': _('Purchase Order'),
- 'domain': domain,
- 'type': 'ir.actions.act_window',
- 'view_mode': 'tree,form',
- 'res_model': 'purchase.order',
+ "name": _("Purchase Order"),
+ "domain": domain,
+ "type": "ir.actions.act_window",
+ "view_mode": "tree,form",
+ "res_model": "purchase.order",
}
- @api.multi
def button_open_purchase_order_line(self):
self.ensure_one()
- domain = [('account_analytic_id', 'in',
- self.mapped('analytic_account_id').ids)]
+ domain = [("account_analytic_id", "in", self.mapped("analytic_account_id").ids)]
return {
- 'name': _('Purchase Order Lines'),
- 'domain': domain,
- 'type': 'ir.actions.act_window',
- 'view_mode': 'tree,form',
- 'res_model': 'purchase.order.line',
+ "name": _("Purchase Order Lines"),
+ "domain": domain,
+ "type": "ir.actions.act_window",
+ "view_mode": "tree,form",
+ "res_model": "purchase.order.line",
}
- @api.multi
def button_open_purchase_invoice(self):
self.ensure_one()
- action = self.env.ref('purchase.action_invoice_pending')
+ action = self.env.ref("account.action_move_in_invoice_type")
action_dict = action.read()[0] if action else {}
- lines = self.env['account.invoice.line'].search([
- ('account_analytic_id', 'in',
- self.mapped('analytic_account_id').ids)])
- domain = expression.AND([
- [('id', 'in', lines.mapped('invoice_id').ids)],
- safe_eval(action.domain or '[]')])
- action_dict.update({'domain': domain})
+ lines = self.env["account.move.line"].search(
+ [("analytic_account_id", "in", self.mapped("analytic_account_id").ids)]
+ )
+ domain = expression.AND(
+ [
+ [("id", "in", lines.mapped("move_id").ids)],
+ safe_eval(action.domain or "[]"),
+ ]
+ )
+ action_dict.update({"domain": domain})
return action_dict
- @api.multi
def button_open_purchase_invoice_line(self):
self.ensure_one()
- domain = [('account_analytic_id', 'in',
- self.mapped('analytic_account_id').ids)]
+ domain = [("analytic_account_id", "in", self.mapped("analytic_account_id").ids)]
return {
- 'name': _('Purchase Invoice Lines'),
- 'domain': domain,
- 'type': 'ir.actions.act_window',
- 'view_mode': 'tree,form',
- 'res_model': 'account.invoice.line',
+ "name": _("Purchase Invoice Lines"),
+ "domain": domain,
+ "type": "ir.actions.act_window",
+ "view_mode": "tree,form",
+ "res_model": "account.move.line",
}
diff --git a/project_purchase_link/readme/CONTRIBUTORS.rst b/project_purchase_link/readme/CONTRIBUTORS.rst
index e3aab202d7..9a5f7e2c98 100644
--- a/project_purchase_link/readme/CONTRIBUTORS.rst
+++ b/project_purchase_link/readme/CONTRIBUTORS.rst
@@ -1,4 +1,3 @@
* Oihane Crucelaegui
* Ana Juaristi
* Alberto Martín Cortada
-
diff --git a/project_purchase_link/readme/USAGE.rst b/project_purchase_link/readme/USAGE.rst
new file mode 100644
index 0000000000..97b4f6b889
--- /dev/null
+++ b/project_purchase_link/readme/USAGE.rst
@@ -0,0 +1,4 @@
+To use this module, you need to:
+
+#. Belong to the "Show Full Accounting Features" and "Analytic Accounting" groups.
+#. On the lines of purchase orders or invoices, indicate the analytical account associated with the project.
diff --git a/project_purchase_link/static/description/icon.png b/project_purchase_link/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d
GIT binary patch
literal 9455
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
z
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
Xviia!U7SGha1wx#SCgwmn*{w2TRX*I
literal 0
HcmV?d00001
diff --git a/project_purchase_link/static/description/index.html b/project_purchase_link/static/description/index.html
index 63ad4cfb76..21f4118076 100644
--- a/project_purchase_link/static/description/index.html
+++ b/project_purchase_link/static/description/index.html
@@ -367,39 +367,48 @@ Project Purchase Link
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
With this module you can access to purchase orders and invoices related to the
project.
Table of contents
+
+
+
To use this module, you need to:
+
+Belong to the “Show Full Accounting Features” and “Analytic Accounting” groups.
+On the lines of purchase orders or invoices, indicate the analytical account associated with the project.
+
+
-
+
Bugs are tracked on GitHub Issues .
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback .
+
feedback .
Do not contact contributors directly about support or help with technical issues.
-
+
-
+
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-
This module is part of the OCA/project project on GitHub.
+
This module is part of the OCA/project project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
diff --git a/project_purchase_link/tests/test_project_purchase_link.py b/project_purchase_link/tests/test_project_purchase_link.py
index f10ce67e01..d901d3c7c8 100644
--- a/project_purchase_link/tests/test_project_purchase_link.py
+++ b/project_purchase_link/tests/test_project_purchase_link.py
@@ -1,73 +1,75 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-from odoo.tools.safe_eval import safe_eval
+# from odoo.osv import expression
from odoo.tests import common
-from odoo.osv import expression
+
+# from odoo.tools.safe_eval import safe_eval
class TestProjectPurchaseUtilities(common.SavepointCase):
@classmethod
def setUpClass(cls):
super(TestProjectPurchaseUtilities, cls).setUpClass()
- cls.project_model = cls.env['project.project']
- cls.project = cls.project_model.create({
- 'name': 'Test Project',
- })
- cls.purchase_model = cls.env['purchase.order']
- cls.purchase = cls.purchase_model.search([
- ('state', 'in', ('draft', 'sent')),
- ], limit=1)
- cls.invoice_model = cls.env['account.invoice']
+ cls.project_model = cls.env["project.project"]
+ cls.project = cls.project_model.create({"name": "Test Project"})
+ cls.purchase_model = cls.env["purchase.order"]
+ cls.purchase = cls.purchase_model.search(
+ [("state", "in", ("draft", "sent")), ("order_line", "!=", False)], limit=1
+ )
+ cls.invoice_model = cls.env["account.move"]
+ cls.invoice_line_model = cls.env["account.move.line"]
def test_project_purchase(self):
self.assertTrue(self.purchase)
- self.purchase.write({
- 'invoice_status': 'to invoice',
- })
+ self.purchase.write({"invoice_status": "to invoice"})
self.assertFalse(self.project.purchase_count)
self.assertFalse(self.project.purchase_line_total)
self.assertFalse(self.project.purchase_invoice_count)
self.assertFalse(self.project.purchase_invoice_line_total)
- self.purchase.order_line[:1].write({
- 'account_analytic_id': self.project.analytic_account_id.id,
- 'price_unit': 50,
- 'product_qty': 4,
- 'qty_received': 4,
- })
+ self.purchase.order_line[:1].write(
+ {
+ "account_analytic_id": self.project.analytic_account_id.id,
+ "price_unit": 50,
+ "product_qty": 4,
+ "qty_received": 4,
+ }
+ )
self.project.invalidate_cache()
self.assertEquals(self.project.purchase_count, 1)
self.assertEquals(self.project.purchase_line_total, 200)
self.assertFalse(self.project.purchase_invoice_count)
self.assertFalse(self.project.purchase_invoice_line_total)
self.purchase.button_confirm()
- invoice = self.invoice_model.create({
- 'partner_id': self.purchase.partner_id.id,
- 'purchase_id': self.purchase.id,
- 'type': 'in_invoice',
- })
- invoice.purchase_order_change()
+ invoice = self.invoice_model.create(
+ {
+ "partner_id": self.purchase.partner_id.id,
+ "purchase_id": self.purchase.id,
+ "type": "in_invoice",
+ }
+ )
+ for line in self.purchase.order_line:
+ categ_id = line.product_id.categ_id
+ account_id = categ_id.property_account_expense_categ_id.id
+ vals = {
+ "move_id": invoice.id,
+ "name": line.name,
+ "account_id": account_id,
+ "analytic_account_id": line.account_analytic_id.id,
+ }
+ self.invoice_line_model.create(vals)
self.project.invalidate_cache()
self.assertEquals(self.project.purchase_invoice_count, 1)
- self.assertEquals(self.project.purchase_invoice_line_total, 200)
purchase_domain = [
- ('account_analytic_id', 'in',
- self.project.mapped('analytic_account_id').ids)]
- purchase_lines = self.env['purchase.order.line'].search(
- purchase_domain)
- order_domain = [('id', 'in', purchase_lines.mapped('order_id').ids)]
+ (
+ "account_analytic_id",
+ "in",
+ self.project.mapped("analytic_account_id").ids,
+ )
+ ]
+ lines = self.env["purchase.order.line"].search(purchase_domain)
+ order_domain = [("id", "in", lines.mapped("order_id").ids)]
purchase_dict = self.project.button_open_purchase_order()
- self.assertEquals(purchase_dict.get('domain'), order_domain)
+ self.assertEquals(purchase_dict.get("domain"), order_domain)
purchase_line_dict = self.project.button_open_purchase_order_line()
- self.assertEquals(
- purchase_line_dict.get('domain'), purchase_domain)
- invoice_lines = self.env['account.invoice.line'].search(
- purchase_domain)
- invoice_action = self.browse_ref('purchase.action_invoice_pending')
- invoice_domain = expression.AND([
- [('id', 'in', invoice_lines.mapped('invoice_id').ids)],
- safe_eval(invoice_action.domain or '[]')])
- invoice_dict = self.project.button_open_purchase_invoice()
- self.assertEquals(invoice_dict.get('domain'), invoice_domain)
- invoice_line_dict = self.project.button_open_purchase_invoice_line()
- self.assertEquals(invoice_line_dict.get('domain'), purchase_domain)
+ self.assertEquals(purchase_line_dict.get("domain"), purchase_domain)
diff --git a/project_purchase_link/views/project_project_view.xml b/project_purchase_link/views/project_project_view.xml
index 44db57bd92..1dfbfefa7d 100644
--- a/project_purchase_link/views/project_project_view.xml
+++ b/project_purchase_link/views/project_project_view.xml
@@ -5,17 +5,49 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
From 1ec2e286dcc4e04bbca7218c70718f2e3b4697e1 Mon Sep 17 00:00:00 2001
From: emagdalena
Date: Fri, 25 Dec 2020 15:22:25 +0100
Subject: [PATCH 05/24] [IMP] project_purchase_link: black, isort, prettier
---
project_purchase_link/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index 54fff81d14..8a8e3aaafa 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -7,7 +7,7 @@
"license": "AGPL-3",
"depends": ["project", "purchase", "hr_timesheet"],
"author": "AvanzOSC, " "Odoo Community Association (OCA)",
- "website": "http://github.com/OCA/project.git",
+ "website": "https://github.com/OCA/project",
"category": "Project",
"data": ["views/project_project_view.xml"],
"installable": True,
From b1cebb9087f6ebb3195b97981aa8dfbe98f4235c Mon Sep 17 00:00:00 2001
From: emagdalena
Date: Fri, 25 Dec 2020 15:23:37 +0100
Subject: [PATCH 06/24] [MIG] project_purchase_link: Migration to 14.0
[FIX] Test account.move type field
[IMP] Tests
[FIX] Tests
[FIX] Tests
[FIX] Tests
[FIX] format
---
project_purchase_link/__manifest__.py | 2 +-
.../tests/test_project_purchase_link.py | 23 ++++++++++++++-----
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index 8a8e3aaafa..cb8d3b79bc 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Project Purchase Link",
- "version": "13.0.1.0.0",
+ "version": "14.0.1.0.0",
"license": "AGPL-3",
"depends": ["project", "purchase", "hr_timesheet"],
"author": "AvanzOSC, " "Odoo Community Association (OCA)",
diff --git a/project_purchase_link/tests/test_project_purchase_link.py b/project_purchase_link/tests/test_project_purchase_link.py
index d901d3c7c8..8fadd14356 100644
--- a/project_purchase_link/tests/test_project_purchase_link.py
+++ b/project_purchase_link/tests/test_project_purchase_link.py
@@ -36,8 +36,8 @@ def test_project_purchase(self):
}
)
self.project.invalidate_cache()
- self.assertEquals(self.project.purchase_count, 1)
- self.assertEquals(self.project.purchase_line_total, 200)
+ self.assertEqual(self.project.purchase_count, 1)
+ self.assertEqual(self.project.purchase_line_total, 200)
self.assertFalse(self.project.purchase_invoice_count)
self.assertFalse(self.project.purchase_invoice_line_total)
self.purchase.button_confirm()
@@ -45,7 +45,6 @@ def test_project_purchase(self):
{
"partner_id": self.purchase.partner_id.id,
"purchase_id": self.purchase.id,
- "type": "in_invoice",
}
)
for line in self.purchase.order_line:
@@ -59,7 +58,7 @@ def test_project_purchase(self):
}
self.invoice_line_model.create(vals)
self.project.invalidate_cache()
- self.assertEquals(self.project.purchase_invoice_count, 1)
+ self.assertEqual(self.project.purchase_invoice_count, 1)
purchase_domain = [
(
"account_analytic_id",
@@ -70,6 +69,18 @@ def test_project_purchase(self):
lines = self.env["purchase.order.line"].search(purchase_domain)
order_domain = [("id", "in", lines.mapped("order_id").ids)]
purchase_dict = self.project.button_open_purchase_order()
- self.assertEquals(purchase_dict.get("domain"), order_domain)
+ self.assertEqual(purchase_dict.get("domain"), order_domain)
purchase_line_dict = self.project.button_open_purchase_order_line()
- self.assertEquals(purchase_line_dict.get("domain"), purchase_domain)
+ self.assertEqual(purchase_line_dict.get("domain"), purchase_domain)
+ invoice_domain = [("id", "in", [invoice.id])] # only one test invoice (line)
+ invoice_dict = self.project.button_open_purchase_invoice()
+ self.assertEqual(invoice_dict.get("domain"), invoice_domain)
+ invoice_line_domain = [
+ (
+ "analytic_account_id",
+ "in",
+ [self.project.analytic_account_id.id], # one test invoice (line)
+ )
+ ]
+ invoice_line_dict = self.project.button_open_purchase_invoice_line()
+ self.assertEqual(invoice_line_dict.get("domain"), invoice_line_domain)
From 38aa6be42ebe7c833b2a7bbfab6ab3d7aa0ab323 Mon Sep 17 00:00:00 2001
From: Zina Rasoamanana
Date: Wed, 8 Feb 2023 18:05:09 +0100
Subject: [PATCH 07/24] [MIG] project_purchase_link: Migration to 16.0
---
project_purchase_link/README.rst | 11 +-
project_purchase_link/__manifest__.py | 2 +-
.../i18n/project_purchase_link.pot | 5 +-
.../models/project_project.py | 123 ++++++++++++++----
project_purchase_link/readme/CONTRIBUTORS.rst | 1 +
.../static/description/index.html | 7 +-
.../tests/test_project_purchase_link.py | 85 +++++++-----
7 files changed, 169 insertions(+), 65 deletions(-)
diff --git a/project_purchase_link/README.rst b/project_purchase_link/README.rst
index d3efadcf36..4f8469e844 100644
--- a/project_purchase_link/README.rst
+++ b/project_purchase_link/README.rst
@@ -14,13 +14,13 @@ Project Purchase Link
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproject-lightgray.png?logo=github
- :target: https://github.com/OCA/project/tree/13.0/project_purchase_link
+ :target: https://github.com/OCA/project/tree/16.0/project_purchase_link
:alt: OCA/project
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/project-13-0/project-13-0-project_purchase_link
+ :target: https://translation.odoo-community.org/projects/project-16-0/project-16-0-project_purchase_link
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/140/13.0
+ :target: https://runbot.odoo-community.org/runbot/140/16.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -47,7 +47,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -65,6 +65,7 @@ Contributors
* Oihane Crucelaegui
* Ana Juaristi
* Alberto Martín Cortada
+* Zina Rasoamanana
Maintainers
~~~~~~~~~~~
@@ -79,6 +80,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-This module is part of the `OCA/project `_ project on GitHub.
+This module is part of the `OCA/project `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index cb8d3b79bc..0462cf92f3 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Project Purchase Link",
- "version": "14.0.1.0.0",
+ "version": "16.0.1.0.0",
"license": "AGPL-3",
"depends": ["project", "purchase", "hr_timesheet"],
"author": "AvanzOSC, " "Odoo Community Association (OCA)",
diff --git a/project_purchase_link/i18n/project_purchase_link.pot b/project_purchase_link/i18n/project_purchase_link.pot
index 991e1002dd..c906241e25 100644
--- a/project_purchase_link/i18n/project_purchase_link.pot
+++ b/project_purchase_link/i18n/project_purchase_link.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 13.0\n"
+"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -29,6 +29,7 @@ msgid "Project"
msgstr ""
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Invoice Lines"
@@ -46,12 +47,14 @@ msgid "Purchase Invoices"
msgstr ""
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order"
msgstr ""
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order Lines"
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 8f492400a3..b60dca1b8c 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -22,13 +22,101 @@ class ProjectProject(models.Model):
compute="_compute_purchase_invoice_info", string="Purchase Invoice Total"
)
+ def _domain_purchase_order(self):
+ query = self.env["purchase.order.line"]._search(
+ [
+ ("order_id.state", "!=", "cancel"),
+ ]
+ )
+ # check if analytic_distribution contains id of analytic account
+ query.add_where(
+ "purchase_order_line.analytic_distribution ?| array[%s]",
+ [str(project.analytic_account_id.id) for project in self],
+ )
+
+ query.order = None
+ query_string, query_param = query.select(
+ "purchase_order_line.order_id as order_id",
+ )
+ self._cr.execute(query_string, query_param)
+ purchase_lines_ids = [
+ int(record.get("order_id")) for record in self._cr.dictfetchall()
+ ]
+ domain = [("id", "in", purchase_lines_ids)]
+ return domain
+
+ def _domain_purchase_order_line(self):
+ query = self.env["purchase.order.line"]._search(
+ [
+ ("order_id.state", "!=", "cancel"),
+ ]
+ )
+ # check if analytic_distribution contains id of analytic account
+ query.add_where(
+ "purchase_order_line.analytic_distribution ?| array[%s]",
+ [str(project.analytic_account_id.id) for project in self],
+ )
+
+ query.order = None
+ query_string, query_param = query.select(
+ "purchase_order_line.id as id",
+ )
+ self._cr.execute(query_string, query_param)
+ purchase_lines_ids = [
+ int(record.get("id")) for record in self._cr.dictfetchall()
+ ]
+ domain = [("id", "in", purchase_lines_ids)]
+ return domain
+
+ def _domain_purchase_invoice(self):
+ query = self.env["account.move.line"]._search(
+ [
+ ("move_id.state", "!=", "cancel"),
+ ]
+ )
+ # check if analytic_distribution contains id of analytic account
+ query.add_where(
+ "account_move_line.analytic_distribution ?| array[%s]",
+ [str(project.analytic_account_id.id) for project in self],
+ )
+ query.order = None
+ query_string, query_param = query.select(
+ "DISTINCT(account_move_line.move_id) as move_id",
+ )
+ self._cr.execute(query_string, query_param)
+ purchase_invoice_ids = [
+ int(record.get("move_id")) for record in self._cr.dictfetchall()
+ ]
+ domain = [("id", "in", purchase_invoice_ids)]
+ return domain
+
+ def _domain_purchase_invoice_line(self):
+ query = self.env["account.move.line"]._search(
+ [
+ ("move_id.state", "!=", "cancel"),
+ ("move_id.move_type", "=", "in_invoice"),
+ ]
+ )
+ # check if analytic_distribution contains id of analytic account
+ query.add_where(
+ "account_move_line.analytic_distribution ?| array[%s]",
+ [str(project.analytic_account_id.id) for project in self],
+ )
+ query.order = None
+ query_string, query_param = query.select(
+ "account_move_line.id as id",
+ )
+ self._cr.execute(query_string, query_param)
+ purchase_invoice_lines_ids = [
+ int(record.get("id")) for record in self._cr.dictfetchall()
+ ]
+ domain = [("id", "in", purchase_invoice_lines_ids)]
+ return domain
+
def _compute_purchase_info(self):
for project in self:
groups = self.env["purchase.order.line"].read_group(
- [
- ("account_analytic_id", "=", project.analytic_account_id.id),
- ("order_id.state", "!=", "cancel"),
- ],
+ project._domain_purchase_order_line(),
["price_subtotal"],
["order_id"],
)
@@ -41,10 +129,7 @@ def _compute_purchase_info(self):
def _compute_purchase_invoice_info(self):
for project in self:
groups = self.env["account.move.line"].read_group(
- [
- ("analytic_account_id", "=", project.analytic_account_id.id),
- ("move_id.state", "!=", "cancel"),
- ],
+ project._domain_purchase_invoice_line(),
["price_subtotal"],
["move_id"],
)
@@ -56,13 +141,9 @@ def _compute_purchase_invoice_info(self):
def button_open_purchase_order(self):
self.ensure_one()
- purchase_lines = self.env["purchase.order.line"].search(
- [("account_analytic_id", "in", self.mapped("analytic_account_id").ids)]
- )
- domain = [("id", "in", purchase_lines.mapped("order_id").ids)]
return {
"name": _("Purchase Order"),
- "domain": domain,
+ "domain": self._domain_purchase_order(),
"type": "ir.actions.act_window",
"view_mode": "tree,form",
"res_model": "purchase.order",
@@ -70,10 +151,9 @@ def button_open_purchase_order(self):
def button_open_purchase_order_line(self):
self.ensure_one()
- domain = [("account_analytic_id", "in", self.mapped("analytic_account_id").ids)]
return {
"name": _("Purchase Order Lines"),
- "domain": domain,
+ "domain": self._domain_purchase_order_line(),
"type": "ir.actions.act_window",
"view_mode": "tree,form",
"res_model": "purchase.order.line",
@@ -82,25 +162,18 @@ def button_open_purchase_order_line(self):
def button_open_purchase_invoice(self):
self.ensure_one()
action = self.env.ref("account.action_move_in_invoice_type")
- action_dict = action.read()[0] if action else {}
- lines = self.env["account.move.line"].search(
- [("analytic_account_id", "in", self.mapped("analytic_account_id").ids)]
- )
+ action_dict = action.sudo().read()[0] if action else {}
domain = expression.AND(
- [
- [("id", "in", lines.mapped("move_id").ids)],
- safe_eval(action.domain or "[]"),
- ]
+ [safe_eval(action.domain or "[]"), self._domain_purchase_invoice()]
)
action_dict.update({"domain": domain})
return action_dict
def button_open_purchase_invoice_line(self):
self.ensure_one()
- domain = [("analytic_account_id", "in", self.mapped("analytic_account_id").ids)]
return {
"name": _("Purchase Invoice Lines"),
- "domain": domain,
+ "domain": self._domain_purchase_invoice_line(),
"type": "ir.actions.act_window",
"view_mode": "tree,form",
"res_model": "account.move.line",
diff --git a/project_purchase_link/readme/CONTRIBUTORS.rst b/project_purchase_link/readme/CONTRIBUTORS.rst
index 9a5f7e2c98..f04f5a2205 100644
--- a/project_purchase_link/readme/CONTRIBUTORS.rst
+++ b/project_purchase_link/readme/CONTRIBUTORS.rst
@@ -1,3 +1,4 @@
* Oihane Crucelaegui
* Ana Juaristi
* Alberto Martín Cortada
+* Zina Rasoamanana
diff --git a/project_purchase_link/static/description/index.html b/project_purchase_link/static/description/index.html
index 21f4118076..a29aaf88fe 100644
--- a/project_purchase_link/static/description/index.html
+++ b/project_purchase_link/static/description/index.html
@@ -367,7 +367,7 @@ Project Purchase Link
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
With this module you can access to purchase orders and invoices related to the
project.
Table of contents
@@ -396,7 +396,7 @@
Bugs are tracked on GitHub Issues .
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback .
+feedback .
Do not contact contributors directly about support or help with technical issues.
@@ -422,7 +423,7 @@
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-
This module is part of the OCA/project project on GitHub.
+
This module is part of the OCA/project project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
diff --git a/project_purchase_link/tests/test_project_purchase_link.py b/project_purchase_link/tests/test_project_purchase_link.py
index 8fadd14356..450b365140 100644
--- a/project_purchase_link/tests/test_project_purchase_link.py
+++ b/project_purchase_link/tests/test_project_purchase_link.py
@@ -1,21 +1,33 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-# from odoo.osv import expression
+from odoo.osv import expression
from odoo.tests import common
+from odoo.tools.safe_eval import safe_eval
-# from odoo.tools.safe_eval import safe_eval
-
-class TestProjectPurchaseUtilities(common.SavepointCase):
+class TestProjectPurchaseUtilities(common.TransactionCase):
@classmethod
def setUpClass(cls):
- super(TestProjectPurchaseUtilities, cls).setUpClass()
+ super().setUpClass()
+ cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.project_model = cls.env["project.project"]
cls.project = cls.project_model.create({"name": "Test Project"})
cls.purchase_model = cls.env["purchase.order"]
- cls.purchase = cls.purchase_model.search(
- [("state", "in", ("draft", "sent")), ("order_line", "!=", False)], limit=1
+ cls.partner = cls.env.ref("base.res_partner_2")
+ cls.product = cls.env["product.product"].create(
+ {
+ "name": "Product Product 4",
+ "standard_price": 500.0,
+ "list_price": 750.0,
+ "type": "consu",
+ "categ_id": cls.env.ref("product.product_category_all").id,
+ }
+ )
+ cls.purchase = cls.purchase_model.create(
+ {
+ "partner_id": cls.partner.id,
+ }
)
cls.invoice_model = cls.env["account.move"]
cls.invoice_line_model = cls.env["account.move.line"]
@@ -27,15 +39,30 @@ def test_project_purchase(self):
self.assertFalse(self.project.purchase_line_total)
self.assertFalse(self.project.purchase_invoice_count)
self.assertFalse(self.project.purchase_invoice_line_total)
- self.purchase.order_line[:1].write(
+ self.purchase.write(
{
- "account_analytic_id": self.project.analytic_account_id.id,
- "price_unit": 50,
- "product_qty": 4,
- "qty_received": 4,
+ "order_line": [
+ (
+ 0,
+ 0,
+ {
+ "name": "Test line",
+ "analytic_distribution": {
+ self.project.analytic_account_id.id: 100
+ },
+ "price_unit": 50,
+ "product_qty": 4,
+ "qty_received": 4,
+ "product_uom": self.product.uom_id.id,
+ "product_id": self.product.id,
+ },
+ )
+ ]
}
)
- self.project.invalidate_cache()
+
+ self.env.invalidate_all()
+
self.assertEqual(self.project.purchase_count, 1)
self.assertEqual(self.project.purchase_line_total, 200)
self.assertFalse(self.project.purchase_invoice_count)
@@ -45,6 +72,7 @@ def test_project_purchase(self):
{
"partner_id": self.purchase.partner_id.id,
"purchase_id": self.purchase.id,
+ "move_type": "in_invoice",
}
)
for line in self.purchase.order_line:
@@ -54,33 +82,30 @@ def test_project_purchase(self):
"move_id": invoice.id,
"name": line.name,
"account_id": account_id,
- "analytic_account_id": line.account_analytic_id.id,
+ "analytic_distribution": line.analytic_distribution,
}
self.invoice_line_model.create(vals)
- self.project.invalidate_cache()
+ self.env.invalidate_all()
self.assertEqual(self.project.purchase_invoice_count, 1)
- purchase_domain = [
- (
- "account_analytic_id",
- "in",
- self.project.mapped("analytic_account_id").ids,
- )
- ]
+
+ purchase_domain = self.project._domain_purchase_order_line()
+
lines = self.env["purchase.order.line"].search(purchase_domain)
order_domain = [("id", "in", lines.mapped("order_id").ids)]
purchase_dict = self.project.button_open_purchase_order()
self.assertEqual(purchase_dict.get("domain"), order_domain)
purchase_line_dict = self.project.button_open_purchase_order_line()
self.assertEqual(purchase_line_dict.get("domain"), purchase_domain)
- invoice_domain = [("id", "in", [invoice.id])] # only one test invoice (line)
+
+ action = self.env.ref("account.action_move_in_invoice_type")
+ invoice_domain = expression.AND(
+ [safe_eval(action.domain or "[]"), self.project._domain_purchase_invoice()]
+ ) # only one test invoice (line)
+
invoice_dict = self.project.button_open_purchase_invoice()
self.assertEqual(invoice_dict.get("domain"), invoice_domain)
- invoice_line_domain = [
- (
- "analytic_account_id",
- "in",
- [self.project.analytic_account_id.id], # one test invoice (line)
- )
- ]
+
+ invoice_line_domain = self.project._domain_purchase_invoice_line()
+
invoice_line_dict = self.project.button_open_purchase_invoice_line()
self.assertEqual(invoice_line_dict.get("domain"), invoice_line_domain)
From 04d884af750582a7cbae943ae60d791162b2df77 Mon Sep 17 00:00:00 2001
From: Weblate
Date: Tue, 13 Jun 2023 15:09:09 +0000
Subject: [PATCH 08/24] Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.
Translation: project-16.0/project-16.0-project_purchase_link
Translate-URL: https://translation.odoo-community.org/projects/project-16-0/project-16-0-project_purchase_link/
---
project_purchase_link/i18n/es.po | 3 +++
project_purchase_link/i18n/sl.po | 3 +++
2 files changed, 6 insertions(+)
diff --git a/project_purchase_link/i18n/es.po b/project_purchase_link/i18n/es.po
index a8c714efeb..782c164168 100644
--- a/project_purchase_link/i18n/es.po
+++ b/project_purchase_link/i18n/es.po
@@ -32,6 +32,7 @@ msgid "Project"
msgstr "Proyecto"
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Invoice Lines"
@@ -50,12 +51,14 @@ msgid "Purchase Invoices"
msgstr "Facturas de compra"
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order"
msgstr "Pedido de compra"
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order Lines"
diff --git a/project_purchase_link/i18n/sl.po b/project_purchase_link/i18n/sl.po
index 45e30e8ecf..8ccffe5c46 100644
--- a/project_purchase_link/i18n/sl.po
+++ b/project_purchase_link/i18n/sl.po
@@ -33,6 +33,7 @@ msgid "Project"
msgstr ""
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Invoice Lines"
@@ -50,12 +51,14 @@ msgid "Purchase Invoices"
msgstr "Prejeti računi"
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order"
msgstr "Nabavni nalog"
#. module: project_purchase_link
+#. odoo-python
#: code:addons/project_purchase_link/models/project_project.py:0
#, python-format
msgid "Purchase Order Lines"
From ec6116fa0d8c5df6a44273e4bb45a81c4d2df323 Mon Sep 17 00:00:00 2001
From: mymage
Date: Thu, 22 Jun 2023 05:49:09 +0000
Subject: [PATCH 09/24] Added translation using Weblate (Italian)
---
project_purchase_link/i18n/it.po | 75 ++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 project_purchase_link/i18n/it.po
diff --git a/project_purchase_link/i18n/it.po b/project_purchase_link/i18n/it.po
new file mode 100644
index 0000000000..0d167e966c
--- /dev/null
+++ b/project_purchase_link/i18n/it.po
@@ -0,0 +1,75 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase_link
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 16.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2023-06-22 08:10+0000\n"
+"Last-Translator: mymage \n"
+"Language-Team: none\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.17\n"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_count
+msgid "# Purchase"
+msgstr "N° acquisto"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_count
+msgid "# Purchase Invoice"
+msgstr "N* fattura di acquisto"
+
+#. module: project_purchase_link
+#: model:ir.model,name:project_purchase_link.model_project_project
+msgid "Project"
+msgstr "Progetto"
+
+#. module: project_purchase_link
+#. odoo-python
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Invoice Lines"
+msgstr "Righe fattura di acquisto"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoice Total"
+msgstr "Totale fatture di acquisto"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoices"
+msgstr "Fatture di acquisto"
+
+#. module: project_purchase_link
+#. odoo-python
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Order"
+msgstr "Ordine di acquisto"
+
+#. module: project_purchase_link
+#. odoo-python
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Lines"
+msgstr "Righe ordine di acquisto"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Total"
+msgstr "Totale acquisti"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchases"
+msgstr "Acquisti"
From a21561fe4476c0e792bde9207bf4e788042f3869 Mon Sep 17 00:00:00 2001
From: Adriano Prado
Date: Mon, 31 Jul 2023 10:08:33 +0000
Subject: [PATCH 10/24] Added translation using Weblate (Portuguese (Brazil))
---
project_purchase_link/README.rst | 15 ++--
project_purchase_link/i18n/pt_BR.po | 75 +++++++++++++++++++
.../static/description/index.html | 38 +++++-----
3 files changed, 104 insertions(+), 24 deletions(-)
create mode 100644 project_purchase_link/i18n/pt_BR.po
diff --git a/project_purchase_link/README.rst b/project_purchase_link/README.rst
index 4f8469e844..ac9f93718d 100644
--- a/project_purchase_link/README.rst
+++ b/project_purchase_link/README.rst
@@ -2,10 +2,13 @@
Project Purchase Link
=====================
-.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+..
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! source digest: sha256:bc3abdd1cd2f2a13f043452d3847993c032e2b1cc99a2a1774a0edfa57f5abdc
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
@@ -19,11 +22,11 @@ Project Purchase Link
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/project-16-0/project-16-0-project_purchase_link
:alt: Translate me on Weblate
-.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/140/16.0
- :alt: Try me on Runbot
+.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/project&target_branch=16.0
+ :alt: Try me on Runboat
-|badge1| |badge2| |badge3| |badge4| |badge5|
+|badge1| |badge2| |badge3| |badge4| |badge5|
With this module you can access to purchase orders and invoices related to the
project.
@@ -46,7 +49,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
-If you spotted it first, help us smashing it by providing a detailed and welcomed
+If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback `_.
Do not contact contributors directly about support or help with technical issues.
diff --git a/project_purchase_link/i18n/pt_BR.po b/project_purchase_link/i18n/pt_BR.po
new file mode 100644
index 0000000000..f9ad419e55
--- /dev/null
+++ b/project_purchase_link/i18n/pt_BR.po
@@ -0,0 +1,75 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase_link
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 16.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2023-07-31 10:11+0000\n"
+"Last-Translator: Adriano Prado \n"
+"Language-Team: none\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 4.17\n"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_count
+msgid "# Purchase"
+msgstr "# Compra"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_count
+msgid "# Purchase Invoice"
+msgstr "# Fatura de Compra"
+
+#. module: project_purchase_link
+#: model:ir.model,name:project_purchase_link.model_project_project
+msgid "Project"
+msgstr "Projeto"
+
+#. module: project_purchase_link
+#. odoo-python
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Invoice Lines"
+msgstr "Linhas da Fatura de Compra"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_invoice_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoice Total"
+msgstr "Total da Fatura de Compra"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Invoices"
+msgstr "Faturas de Compra"
+
+#. module: project_purchase_link
+#. odoo-python
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Order"
+msgstr "Pedido de Compra"
+
+#. module: project_purchase_link
+#. odoo-python
+#: code:addons/project_purchase_link/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Lines"
+msgstr "Linhas do Pedido de Compra"
+
+#. module: project_purchase_link
+#: model:ir.model.fields,field_description:project_purchase_link.field_project_project__purchase_line_total
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchase Total"
+msgstr "Total Compra"
+
+#. module: project_purchase_link
+#: model_terms:ir.ui.view,arch_db:project_purchase_link.project_project_view_form
+msgid "Purchases"
+msgstr "Compras"
diff --git a/project_purchase_link/static/description/index.html b/project_purchase_link/static/description/index.html
index a29aaf88fe..b5a1cdba37 100644
--- a/project_purchase_link/static/description/index.html
+++ b/project_purchase_link/static/description/index.html
@@ -1,20 +1,20 @@
-
+
-
+
Project Purchase Link
-
-
Project Purchase Link
+
+
+
+
+
+
+
Project Purchase Link
-
+
With this module you can access to purchase orders and invoices related
to the project.
Table of contents
@@ -386,7 +391,7 @@
Project Purchase Link
-
+
To use this module, you need to:
Belong to the “Show Full Accounting Features” and “Analytic
@@ -396,23 +401,23 @@
-
+
Bugs are tracked on GitHub Issues .
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback .
+
feedback .
Do not contact contributors directly about support or help with technical issues.
+
From 0bd65b8c74e6c0c159a7bb8c1e40b781ec6ab6af Mon Sep 17 00:00:00 2001
From: solomonprabu
Date: Thu, 16 Jul 2026 14:58:37 +0530
Subject: [PATCH 19/24] [MIG] Migration to 19.0
---
.../models/project_project.py | 37 ++++++++-----------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 970979a6ef..8c6841b449 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -2,7 +2,7 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from odoo import fields, models
-from odoo.osv import expression
+from odoo.fields import Domain
from odoo.tools.safe_eval import safe_eval
@@ -38,11 +38,11 @@ def _domain_purchase_order(self):
query_string, query_param = query.select(
"purchase_order_line.order_id as order_id",
)
- self._cr.execute(query_string, query_param)
+ self.env.cr.execute(query_string, query_param)
purchase_lines_ids = [
- int(record.get("order_id")) for record in self._cr.dictfetchall()
+ int(record.get("order_id")) for record in self.env.cr.dictfetchall()
]
- domain = [("id", "in", purchase_lines_ids)]
+ domain = Domain([("id", "in", purchase_lines_ids)])
return domain
def _domain_purchase_order_line(self):
@@ -61,11 +61,11 @@ def _domain_purchase_order_line(self):
query_string, query_param = query.select(
"purchase_order_line.id as id",
)
- self._cr.execute(query_string, query_param)
+ self.env.cr.execute(query_string, query_param)
purchase_lines_ids = [
- int(record.get("id")) for record in self._cr.dictfetchall()
+ int(record.get("id")) for record in self.env.cr.dictfetchall()
]
- domain = [("id", "in", purchase_lines_ids)]
+ domain = Domain([("id", "in", purchase_lines_ids)])
return domain
def _domain_purchase_invoice(self):
@@ -83,11 +83,11 @@ def _domain_purchase_invoice(self):
query_string, query_param = query.select(
"DISTINCT(account_move_line.move_id) as move_id",
)
- self._cr.execute(query_string, query_param)
+ self.env.cr.execute(query_string, query_param)
purchase_invoice_ids = [
- int(record.get("move_id")) for record in self._cr.dictfetchall()
+ int(record.get("move_id")) for record in self.env.cr.dictfetchall()
]
- domain = [("id", "in", purchase_invoice_ids)]
+ domain = Domain([("id", "in", purchase_invoice_ids)])
return domain
def _domain_purchase_invoice_line(self):
@@ -106,16 +106,16 @@ def _domain_purchase_invoice_line(self):
query_string, query_param = query.select(
"account_move_line.id as id",
)
- self._cr.execute(query_string, query_param)
+ self.env.cr.execute(query_string, query_param)
purchase_invoice_lines_ids = [
- int(record.get("id")) for record in self._cr.dictfetchall()
+ int(record.get("id")) for record in self.env.cr.dictfetchall()
]
- domain = [("id", "in", purchase_invoice_lines_ids)]
+ domain = Domain([("id", "in", purchase_invoice_lines_ids)])
return domain
def _compute_purchase_info(self):
for project in self:
- groups = self.env["purchase.order.line"].read_group(
+ groups = self.env["purchase.order.line"]._read_group(
project._domain_purchase_order_line(),
["order_id"],
["price_subtotal"],
@@ -128,7 +128,7 @@ def _compute_purchase_info(self):
def _compute_purchase_invoice_info(self):
for project in self:
- groups = self.env["account.move.line"].read_group(
+ groups = self.env["account.move.line"]._read_group(
project._domain_purchase_invoice_line(),
["price_subtotal"],
["move_id"],
@@ -164,12 +164,7 @@ def button_open_purchase_invoice(self):
action = self.env["ir.actions.act_window"]._for_xml_id(
"account.action_move_in_invoice_type"
)
- domain = expression.AND(
- [
- safe_eval(action.get("domain", "[]")),
- self._domain_purchase_invoice(),
- ]
- )
+ domain = Domain(safe_eval(action.get("domain", "[]"))) & self._domain_purchase_invoice()
action.update({"domain": domain})
return action
From 055b7888c9895464ee706477a10e013e4e065b0e Mon Sep 17 00:00:00 2001
From: solomonprabu
Date: Thu, 16 Jul 2026 15:31:46 +0530
Subject: [PATCH 20/24] [FIX] migration code fix and pre-commit fixes
---
project_purchase_link/models/project_project.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 8c6841b449..54d78c63c2 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -115,7 +115,7 @@ def _domain_purchase_invoice_line(self):
def _compute_purchase_info(self):
for project in self:
- groups = self.env["purchase.order.line"]._read_group(
+ groups = self.env["purchase.order.line"].formatted_read_group(
project._domain_purchase_order_line(),
["order_id"],
["price_subtotal"],
@@ -128,7 +128,7 @@ def _compute_purchase_info(self):
def _compute_purchase_invoice_info(self):
for project in self:
- groups = self.env["account.move.line"]._read_group(
+ groups = self.env["account.move.line"].formattedformatted_read_group(
project._domain_purchase_invoice_line(),
["price_subtotal"],
["move_id"],
@@ -164,7 +164,10 @@ def button_open_purchase_invoice(self):
action = self.env["ir.actions.act_window"]._for_xml_id(
"account.action_move_in_invoice_type"
)
- domain = Domain(safe_eval(action.get("domain", "[]"))) & self._domain_purchase_invoice()
+ domain = (
+ Domain(safe_eval(action.get("domain", "[]")))
+ & self._domain_purchase_invoice()
+ )
action.update({"domain": domain})
return action
From ae4c7ef7e1a688478c6363aad8e8bad4b185e909 Mon Sep 17 00:00:00 2001
From: solomonprabu
Date: Thu, 16 Jul 2026 15:42:00 +0530
Subject: [PATCH 21/24] [FIX] Typo
---
project_purchase_link/__init__.py | 1 +
project_purchase_link/__manifest__.py | 1 +
project_purchase_link/models/__init__.py | 1 +
project_purchase_link/models/project_project.py | 3 ++-
project_purchase_link/tests/test_project_purchase_link.py | 1 +
5 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/project_purchase_link/__init__.py b/project_purchase_link/__init__.py
index 4209851d55..afbde48052 100644
--- a/project_purchase_link/__init__.py
+++ b/project_purchase_link/__init__.py
@@ -1,4 +1,5 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# Copyright 2026 Solomon Prabu - CIT Services
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from . import models
diff --git a/project_purchase_link/__manifest__.py b/project_purchase_link/__manifest__.py
index f693f07722..9ef9c47457 100644
--- a/project_purchase_link/__manifest__.py
+++ b/project_purchase_link/__manifest__.py
@@ -1,4 +1,5 @@
# Copyright 2018 Gontzal Gomez - AvanzOSC
+# Copyright 2026 Solomon Prabu - CIT Services
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
diff --git a/project_purchase_link/models/__init__.py b/project_purchase_link/models/__init__.py
index 6fe88855d5..b0b99c5083 100644
--- a/project_purchase_link/models/__init__.py
+++ b/project_purchase_link/models/__init__.py
@@ -1,4 +1,5 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# Copyright 2026 Solomon Prabu - CIT Services
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from . import project_project
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 54d78c63c2..485c19983c 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -1,4 +1,5 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# Copyright 2026 Solomon Prabu - CIT Services
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from odoo import fields, models
@@ -128,7 +129,7 @@ def _compute_purchase_info(self):
def _compute_purchase_invoice_info(self):
for project in self:
- groups = self.env["account.move.line"].formattedformatted_read_group(
+ groups = self.env["account.move.line"].formatted_read_group(
project._domain_purchase_invoice_line(),
["price_subtotal"],
["move_id"],
diff --git a/project_purchase_link/tests/test_project_purchase_link.py b/project_purchase_link/tests/test_project_purchase_link.py
index 88460a2e45..4e2e3a31b6 100644
--- a/project_purchase_link/tests/test_project_purchase_link.py
+++ b/project_purchase_link/tests/test_project_purchase_link.py
@@ -1,4 +1,5 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
+# Copyright 2026 Solomon Prabu - CIT Services
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from odoo import Command
From bfaeda5d8b09d3b5e2ea957682f41cbf8c7a27e6 Mon Sep 17 00:00:00 2001
From: solomonprabu
Date: Thu, 16 Jul 2026 16:03:51 +0530
Subject: [PATCH 22/24] [FIX] project_purchase_link: fix read_group calls
---
.../models/project_project.py | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 485c19983c..c250a3a945 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -116,29 +116,23 @@ def _domain_purchase_invoice_line(self):
def _compute_purchase_info(self):
for project in self:
- groups = self.env["purchase.order.line"].formatted_read_group(
+ groups = self.env["purchase.order.line"]._read_group(
project._domain_purchase_order_line(),
["order_id"],
- ["price_subtotal"],
+ ["price_subtotal:sum"],
)
- purchase_line_total = 0
- for group in groups:
- purchase_line_total += group["price_subtotal"]
project.purchase_count = len(groups)
- project.purchase_line_total = purchase_line_total
+ project.purchase_line_total = sum(price_subtotal for _order_id, price_subtotal in groups)
def _compute_purchase_invoice_info(self):
for project in self:
- groups = self.env["account.move.line"].formatted_read_group(
+ groups = self.env["account.move.line"]._read_group(
project._domain_purchase_invoice_line(),
- ["price_subtotal"],
["move_id"],
+ ["price_subtotal:sum"],
)
- purchase_invoice_line_total = 0
- for group in groups:
- purchase_invoice_line_total += group["price_subtotal"]
project.purchase_invoice_count = len(groups)
- project.purchase_invoice_line_total = purchase_invoice_line_total
+ project.purchase_invoice_line_total = sum(price_subtotal for _move_id, price_subtotal in groups)
def button_open_purchase_order(self):
self.ensure_one()
From 5471cc573de8b7404b386110dad9141765a118a1 Mon Sep 17 00:00:00 2001
From: solomonprabu
Date: Thu, 16 Jul 2026 16:04:52 +0530
Subject: [PATCH 23/24] [FIX] project_purchase_link: fix read_group calls -
Replaced with
---
project_purchase_link/models/project_project.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index c250a3a945..53cfe01d4f 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -122,7 +122,9 @@ def _compute_purchase_info(self):
["price_subtotal:sum"],
)
project.purchase_count = len(groups)
- project.purchase_line_total = sum(price_subtotal for _order_id, price_subtotal in groups)
+ project.purchase_line_total = sum(
+ price_subtotal for _order_id, price_subtotal in groups
+ )
def _compute_purchase_invoice_info(self):
for project in self:
@@ -132,7 +134,9 @@ def _compute_purchase_invoice_info(self):
["price_subtotal:sum"],
)
project.purchase_invoice_count = len(groups)
- project.purchase_invoice_line_total = sum(price_subtotal for _move_id, price_subtotal in groups)
+ project.purchase_invoice_line_total = sum(
+ price_subtotal for _move_id, price_subtotal in groups
+ )
def button_open_purchase_order(self):
self.ensure_one()
From ac96afa0573f3b69dbda1a5d951d6be42db7d1ae Mon Sep 17 00:00:00 2001
From: solomonprabu
Date: Thu, 16 Jul 2026 16:30:28 +0530
Subject: [PATCH 24/24] [FIX] Fixed sql_query object usage and Domain usage
---
project_purchase_link/models/project_project.py | 16 ++++++++--------
.../tests/test_project_purchase_link.py | 15 ++++++++-------
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/project_purchase_link/models/project_project.py b/project_purchase_link/models/project_project.py
index 53cfe01d4f..54fb23488b 100644
--- a/project_purchase_link/models/project_project.py
+++ b/project_purchase_link/models/project_project.py
@@ -36,10 +36,10 @@ def _domain_purchase_order(self):
)
query.order = None
- query_string, query_param = query.select(
+ query_sql = query.select(
"purchase_order_line.order_id as order_id",
)
- self.env.cr.execute(query_string, query_param)
+ self.env.cr.execute(query_sql.code, query_sql.params)
purchase_lines_ids = [
int(record.get("order_id")) for record in self.env.cr.dictfetchall()
]
@@ -59,10 +59,10 @@ def _domain_purchase_order_line(self):
)
query.order = None
- query_string, query_param = query.select(
+ query_sql = query.select(
"purchase_order_line.id as id",
)
- self.env.cr.execute(query_string, query_param)
+ self.env.cr.execute(query_sql.code, query_sql.params)
purchase_lines_ids = [
int(record.get("id")) for record in self.env.cr.dictfetchall()
]
@@ -81,10 +81,10 @@ def _domain_purchase_invoice(self):
[str(project.account_id.id) for project in self],
)
query.order = None
- query_string, query_param = query.select(
+ query_sql = query.select(
"DISTINCT(account_move_line.move_id) as move_id",
)
- self.env.cr.execute(query_string, query_param)
+ self.env.cr.execute(query_sql.code, query_sql.params)
purchase_invoice_ids = [
int(record.get("move_id")) for record in self.env.cr.dictfetchall()
]
@@ -104,10 +104,10 @@ def _domain_purchase_invoice_line(self):
[str(project.account_id.id) for project in self],
)
query.order = None
- query_string, query_param = query.select(
+ query_sql = query.select(
"account_move_line.id as id",
)
- self.env.cr.execute(query_string, query_param)
+ self.env.cr.execute(query_sql.code, query_sql.params)
purchase_invoice_lines_ids = [
int(record.get("id")) for record in self.env.cr.dictfetchall()
]
diff --git a/project_purchase_link/tests/test_project_purchase_link.py b/project_purchase_link/tests/test_project_purchase_link.py
index 4e2e3a31b6..f5b6397750 100644
--- a/project_purchase_link/tests/test_project_purchase_link.py
+++ b/project_purchase_link/tests/test_project_purchase_link.py
@@ -3,7 +3,7 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from odoo import Command
-from odoo.osv import expression
+from odoo.fields import Domain
from odoo.tools.safe_eval import safe_eval
from odoo.addons.base.tests.common import BaseCommon
@@ -17,14 +17,14 @@ def setUpClass(cls):
cls.project_model = cls.env["project.project"]
cls.project = cls.project_model.create({"name": "Test Project"})
cls.purchase_model = cls.env["purchase.order"]
- cls.partner = cls.env.ref("base.res_partner_2")
+ cls.partner = cls.env["res.partner"].create({"name": "Test Partner"})
cls.product = cls.env["product.product"].create(
{
"name": "Product Product 4",
"standard_price": 500.0,
"list_price": 750.0,
"type": "consu",
- "categ_id": cls.env.ref("product.product_category_all").id,
+ "categ_id": cls.env["product.category"].search([], limit=1).id,
}
)
cls.purchase = cls.purchase_model.create(
@@ -52,7 +52,7 @@ def test_project_purchase(self):
"price_unit": 50,
"product_qty": 4,
"qty_received": 4,
- "product_uom": self.product.uom_id.id,
+ "product_uom_id": self.product.uom_id.id,
"product_id": self.product.id,
}
)
@@ -90,15 +90,16 @@ def test_project_purchase(self):
purchase_domain = self.project._domain_purchase_order_line()
lines = self.env["purchase.order.line"].search(purchase_domain)
- order_domain = [("id", "in", lines.mapped("order_id").ids)]
+ order_domain = Domain([("id", "in", lines.mapped("order_id").ids)])
purchase_dict = self.project.button_open_purchase_order()
self.assertEqual(purchase_dict.get("domain"), order_domain)
purchase_line_dict = self.project.button_open_purchase_order_line()
self.assertEqual(purchase_line_dict.get("domain"), purchase_domain)
action = self.env.ref("account.action_move_in_invoice_type")
- invoice_domain = expression.AND(
- [safe_eval(action.domain or "[]"), self.project._domain_purchase_invoice()]
+ invoice_domain = (
+ Domain(safe_eval(action.domain or "[]"))
+ & self.project._domain_purchase_invoice()
) # only one test invoice (line)
invoice_dict = self.project.button_open_purchase_invoice()