diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..be9f4fa
--- /dev/null
+++ b/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import models
diff --git a/__manifest__.py b/__manifest__.py
new file mode 100644
index 0000000..3b2b330
--- /dev/null
+++ b/__manifest__.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+ 'name': "Project Purchase",
+ 'version': '1.0',
+ 'summary': "Monitor purchase in project",
+ 'category': 'Services/Project',
+ 'depends': ['purchase', 'project_account'],
+ 'demo': [
+ 'data/project_purchase_demo.xml',
+ ],
+ 'auto_install': True,
+ 'license': 'LGPL-3',
+}
diff --git a/data/project_purchase_demo.xml b/data/project_purchase_demo.xml
new file mode 100644
index 0000000..b40f186
--- /dev/null
+++ b/data/project_purchase_demo.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/i18n/ar.po b/i18n/ar.po
new file mode 100644
index 0000000..0530b2b
--- /dev/null
+++ b/i18n/ar.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Arabic (https://app.transifex.com/odoo/teams/41243/ar/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: ar\n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "عدد أوامر الشراء "
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "المشروع"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "عناصر أمر البيع "
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "بند أمر الشراء"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "أوامر الشراء"
diff --git a/i18n/bg.po b/i18n/bg.po
new file mode 100644
index 0000000..cfa35c1
--- /dev/null
+++ b/i18n/bg.po
@@ -0,0 +1,53 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# aleksandar ivanov, 2023
+# Maria Boyadjieva , 2023
+# Martin Trigaux, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Martin Trigaux, 2023\n"
+"Language-Team: Bulgarian (https://app.transifex.com/odoo/teams/41243/bg/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: bg\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Проект"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Ред на поръчка за покупка"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Поръчки за покупки"
diff --git a/i18n/ca.po b/i18n/ca.po
new file mode 100644
index 0000000..b8b0dd6
--- /dev/null
+++ b/i18n/ca.po
@@ -0,0 +1,55 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# marcescu, 2023
+# Martin Trigaux, 2023
+# Ivan Espinola, 2023
+# Manel Fernandez Ramirez , 2023
+# Quim - eccit , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Quim - eccit , 2023\n"
+"Language-Team: Catalan (https://app.transifex.com/odoo/teams/41243/ca/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: ca\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Ordres de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projecte"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Elements de comanda de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Línia de la comanda de compra"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Comandes de compra"
diff --git a/i18n/cs.po b/i18n/cs.po
new file mode 100644
index 0000000..488411a
--- /dev/null
+++ b/i18n/cs.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Ivana Bartonkova, 2023
+# Jakub Smolka, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Jakub Smolka, 2023\n"
+"Language-Team: Czech (https://app.transifex.com/odoo/teams/41243/cs/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: cs\n"
+"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekty"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Položka nákupní objednávky"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Nákupní objednávky"
diff --git a/i18n/da.po b/i18n/da.po
new file mode 100644
index 0000000..93c3123
--- /dev/null
+++ b/i18n/da.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Martin Trigaux, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Martin Trigaux, 2023\n"
+"Language-Team: Danish (https://app.transifex.com/odoo/teams/41243/da/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Indkøbsordrelinie"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Indkøbsordrer"
diff --git a/i18n/de.po b/i18n/de.po
new file mode 100644
index 0000000..aef84f3
--- /dev/null
+++ b/i18n/de.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: German (https://app.transifex.com/odoo/teams/41243/de/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Bestellungen"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Bestellpositionen"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Bestellzeile"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Bestellungen"
diff --git a/i18n/es.po b/i18n/es.po
new file mode 100644
index 0000000..daea3d1
--- /dev/null
+++ b/i18n/es.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+# Larissa Manderfeld, 2024
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Larissa Manderfeld, 2024\n"
+"Language-Team: Spanish (https://app.transifex.com/odoo/teams/41243/es/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: es\n"
+"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Órdenes de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Proyecto"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Artículos de la orden de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Línea de orden de compra"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Órdenes de compra"
diff --git a/i18n/es_419.po b/i18n/es_419.po
new file mode 100644
index 0000000..1c7d93c
--- /dev/null
+++ b/i18n/es_419.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+# Fernanda Alvarez, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Fernanda Alvarez, 2023\n"
+"Language-Team: Spanish (Latin America) (https://app.transifex.com/odoo/teams/41243/es_419/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: es_419\n"
+"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "Número de órdenes de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Proyecto"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Artículos de la orden de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Línea de la orden de compra"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Órdenes de compra"
diff --git a/i18n/et.po b/i18n/et.po
new file mode 100644
index 0000000..cf72851
--- /dev/null
+++ b/i18n/et.po
@@ -0,0 +1,53 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Eneli Õigus , 2023
+# JanaAvalah, 2023
+# Patrick-Jordan Kiudorv, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Patrick-Jordan Kiudorv, 2023\n"
+"Language-Team: Estonian (https://app.transifex.com/odoo/teams/41243/et/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: et\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Ostutellimused"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projektid"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Ostutellimuse kaubad"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Ostutellimuse rida"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Ostutellimused"
diff --git a/i18n/fa.po b/i18n/fa.po
new file mode 100644
index 0000000..a253aec
--- /dev/null
+++ b/i18n/fa.po
@@ -0,0 +1,54 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Hanna Kheradroosta, 2023
+# Hamid Darabi, 2023
+# Hamed Mohammadi , 2023
+# Martin Trigaux, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Martin Trigaux, 2023\n"
+"Language-Team: Persian (https://app.transifex.com/odoo/teams/41243/fa/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: fa\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# سفارشات خرید"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "پروژه"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "سطر سفارش خرید"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "سفارشات خرید"
diff --git a/i18n/fi.po b/i18n/fi.po
new file mode 100644
index 0000000..537a608
--- /dev/null
+++ b/i18n/fi.po
@@ -0,0 +1,54 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Martin Trigaux, 2023
+# Ossi Mantylahti , 2023
+# Tuomo Aura , 2023
+# Svante Suominen , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Svante Suominen , 2023\n"
+"Language-Team: Finnish (https://app.transifex.com/odoo/teams/41243/fi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: fi\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Ostotilausta"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projektit"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Ostotilauksen kohteet"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Ostotilausrivi"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Ostotilaukset"
diff --git a/i18n/fr.po b/i18n/fr.po
new file mode 100644
index 0000000..7274d4e
--- /dev/null
+++ b/i18n/fr.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: French (https://app.transifex.com/odoo/teams/41243/fr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: fr\n"
+"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Bons de commande"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projet"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Lignes de commande d'achat"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Ligne de bon de commande"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Bons de commande"
diff --git a/i18n/he.po b/i18n/he.po
new file mode 100644
index 0000000..197e0b3
--- /dev/null
+++ b/i18n/he.po
@@ -0,0 +1,54 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Yihya Hugirat , 2023
+# דודי מלכה , 2023
+# Roy Sayag, 2023
+# ZVI BLONDER , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: ZVI BLONDER , 2023\n"
+"Language-Team: Hebrew (https://app.transifex.com/odoo/teams/41243/he/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: he\n"
+"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# הזמנות רכש"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "פרויקט"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "שורת הזמנת רכש"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "הזמנות רכש"
diff --git a/i18n/hu.po b/i18n/hu.po
new file mode 100644
index 0000000..86b9eda
--- /dev/null
+++ b/i18n/hu.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Ákos Nagy , 2023
+# Tamás Németh , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Tamás Németh , 2023\n"
+"Language-Team: Hungarian (https://app.transifex.com/odoo/teams/41243/hu/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: hu\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Beszerzési rendelés tétel"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Beszerzési rendelések"
diff --git a/i18n/id.po b/i18n/id.po
new file mode 100644
index 0000000..a434737
--- /dev/null
+++ b/i18n/id.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Indonesian (https://app.transifex.com/odoo/teams/41243/id/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: id\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# SPB"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Proyek"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Item SPB"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Baris Order Pembelian"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Order Pembelian"
diff --git a/i18n/it.po b/i18n/it.po
new file mode 100644
index 0000000..26dd330
--- /dev/null
+++ b/i18n/it.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Italian (https://app.transifex.com/odoo/teams/41243/it/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: it\n"
+"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "N. ordini di acquisto"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Progetto"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Articoli ordine di acquisto"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Riga ordine di acquisto"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Ordini di acquisto"
diff --git a/i18n/ja.po b/i18n/ja.po
new file mode 100644
index 0000000..abb16e9
--- /dev/null
+++ b/i18n/ja.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Japanese (https://app.transifex.com/odoo/teams/41243/ja/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: ja\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "購買オーダ数"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "プロジェクト"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "購買オーダ項目"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "購買オーダ明細"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "購買オーダ"
diff --git a/i18n/ko.po b/i18n/ko.po
new file mode 100644
index 0000000..51d3b1f
--- /dev/null
+++ b/i18n/ko.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Korean (https://app.transifex.com/odoo/teams/41243/ko/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: ko\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# 발주서"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "프로젝트"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "구매발주서 항목"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "발주서 내역"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "구매 주문"
diff --git a/i18n/lt.po b/i18n/lt.po
new file mode 100644
index 0000000..e535605
--- /dev/null
+++ b/i18n/lt.po
@@ -0,0 +1,53 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Jonas Zinkevicius , 2023
+# Linas Versada , 2023
+# Martin Trigaux, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Martin Trigaux, 2023\n"
+"Language-Team: Lithuanian (https://app.transifex.com/odoo/teams/41243/lt/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: lt\n"
+"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "Pirkimo užsakymo nr."
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projektas"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Pirkimo užsakymo eilutė "
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Pirkimų užsakymai"
diff --git a/i18n/lv.po b/i18n/lv.po
new file mode 100644
index 0000000..15d2631
--- /dev/null
+++ b/i18n/lv.po
@@ -0,0 +1,53 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Arnis Putniņš , 2023
+# Konstantins Zabogonskis , 2023
+# ievaputnina , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: ievaputnina , 2023\n"
+"Language-Team: Latvian (https://app.transifex.com/odoo/teams/41243/lv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: lv\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekti"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Pasūtījuma rinda"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Pirkuma Pasūtījumi"
diff --git a/i18n/nl.po b/i18n/nl.po
new file mode 100644
index 0000000..479a326
--- /dev/null
+++ b/i18n/nl.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+# Erwin van der Ploeg , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Erwin van der Ploeg , 2023\n"
+"Language-Team: Dutch (https://app.transifex.com/odoo/teams/41243/nl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: nl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Inkooporders"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Project"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Inkooporderregels"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Inkooporderregel"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Inkooporders"
diff --git a/i18n/pl.po b/i18n/pl.po
new file mode 100644
index 0000000..1e6174d
--- /dev/null
+++ b/i18n/pl.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Polish (https://app.transifex.com/odoo/teams/41243/pl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: pl\n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "#Zamówienia zakupu"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Pozycje zamówienia zakupu"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Pozycja zamówienia zakupu"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Zamówienia Zakupu"
diff --git a/i18n/project_purchase.pot b/i18n/project_purchase.pot
new file mode 100644
index 0000000..5d96261
--- /dev/null
+++ b/i18n/project_purchase.pot
@@ -0,0 +1,47 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 21:55+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
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr ""
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr ""
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr ""
diff --git a/i18n/pt.po b/i18n/pt.po
new file mode 100644
index 0000000..0e75901
--- /dev/null
+++ b/i18n/pt.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Portuguese (https://app.transifex.com/odoo/teams/41243/pt/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: pt\n"
+"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Pedidos de Compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projeto"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Linha de Encomenda de Compra"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Pedidos de Compra"
diff --git a/i18n/pt_BR.po b/i18n/pt_BR.po
new file mode 100644
index 0000000..a2858c0
--- /dev/null
+++ b/i18n/pt_BR.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+# Maitê Dietze, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Maitê Dietze, 2023\n"
+"Language-Team: Portuguese (Brazil) (https://app.transifex.com/odoo/teams/41243/pt_BR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: pt_BR\n"
+"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "Nº de pedidos de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projeto"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Itens do pedido de compra"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Linha do pedido de compra"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Pedidos de compra"
diff --git a/i18n/ru.po b/i18n/ru.po
new file mode 100644
index 0000000..bbeb187
--- /dev/null
+++ b/i18n/ru.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Сергей Шебанин , 2023
+# Wil Odoo, 2024
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2024\n"
+"Language-Team: Russian (https://app.transifex.com/odoo/teams/41243/ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: ru\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Заказы на покупку"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Проект"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Пункты заказа на поставку"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Позиция заказа на покупку"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Заказы на покупку"
diff --git a/i18n/sk.po b/i18n/sk.po
new file mode 100644
index 0000000..8ab8c3b
--- /dev/null
+++ b/i18n/sk.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Slovak (https://app.transifex.com/odoo/teams/41243/sk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: sk\n"
+"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Riadok nákupnej objednávky"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Nakupné objednávky"
diff --git a/i18n/sl.po b/i18n/sl.po
new file mode 100644
index 0000000..fb21047
--- /dev/null
+++ b/i18n/sl.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Martin Trigaux, 2023
+# Katja Deržič, 2024
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Katja Deržič, 2024\n"
+"Language-Team: Slovenian (https://app.transifex.com/odoo/teams/41243/sl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: sl\n"
+"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "Nabavni nalog"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr ""
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Postavka nabavnega naloga"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Nabavni nalogi"
diff --git a/i18n/sr.po b/i18n/sr.po
new file mode 100644
index 0000000..8c6c8db
--- /dev/null
+++ b/i18n/sr.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Milan Bojovic, 2023
+# Dragan Vukosavljevic , 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Dragan Vukosavljevic , 2023\n"
+"Language-Team: Serbian (https://app.transifex.com/odoo/teams/41243/sr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: sr\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Zahteva za nabavku"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekat"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Stavke naloga za nabavku"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Linija naloga za nabavku"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Nalozi za nabavku"
diff --git a/i18n/sv.po b/i18n/sv.po
new file mode 100644
index 0000000..29fd119
--- /dev/null
+++ b/i18n/sv.po
@@ -0,0 +1,53 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Kim Asplund , 2023
+# Lasse L, 2023
+# Martin Trigaux, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Martin Trigaux, 2023\n"
+"Language-Team: Swedish (https://app.transifex.com/odoo/teams/41243/sv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Inköpsordrar"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Projekt"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Poster i inköpsorder"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Inköpsorderrad"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Inköpsordrar"
diff --git a/i18n/th.po b/i18n/th.po
new file mode 100644
index 0000000..30abcc2
--- /dev/null
+++ b/i18n/th.po
@@ -0,0 +1,52 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+# Rasareeyar Lappiam, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Rasareeyar Lappiam, 2023\n"
+"Language-Team: Thai (https://app.transifex.com/odoo/teams/41243/th/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: th\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# ใบสั่งซื้อ"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "โปรเจ็กต์"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "รายการใบสั่งซื้อ"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "รายการคำสั่งซื้อ"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "คำสั่งซื้อ"
diff --git a/i18n/tr.po b/i18n/tr.po
new file mode 100644
index 0000000..7c296ae
--- /dev/null
+++ b/i18n/tr.po
@@ -0,0 +1,53 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Murat Kaplan , 2023
+# Tugay Hatıl , 2023
+# Martin Trigaux, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Martin Trigaux, 2023\n"
+"Language-Team: Turkish (https://app.transifex.com/odoo/teams/41243/tr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: tr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Satınalma Siparişleri"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Proje"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Satınalma Sipariş Satırları"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Satınalma Sipariş Satırı"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Satınalma Siparişleri"
diff --git a/i18n/uk.po b/i18n/uk.po
new file mode 100644
index 0000000..6179e1d
--- /dev/null
+++ b/i18n/uk.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Ukrainian (https://app.transifex.com/odoo/teams/41243/uk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: uk\n"
+"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "К-сть замовлень на купівлю"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Проект"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Рядки замовлення на купівлю"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Рядок замовлення на купівлю"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Замовлення на купівлю"
diff --git a/i18n/vi.po b/i18n/vi.po
new file mode 100644
index 0000000..3fcf2fc
--- /dev/null
+++ b/i18n/vi.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Vietnamese (https://app.transifex.com/odoo/teams/41243/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# Đơn mua hàng"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "Dự án"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "Hạng mục đơn mua hàng"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Dòng đơn mua hàng"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "Đơn mua hàng"
diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po
new file mode 100644
index 0000000..ba429ed
--- /dev/null
+++ b/i18n/zh_CN.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Chinese (China) (https://app.transifex.com/odoo/teams/41243/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "# 采购订单"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "项目"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "采购订单项目"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "采购订单明细"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "采购订单"
diff --git a/i18n/zh_TW.po b/i18n/zh_TW.po
new file mode 100644
index 0000000..78af147
--- /dev/null
+++ b/i18n/zh_TW.po
@@ -0,0 +1,51 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * project_purchase
+#
+# Translators:
+# Wil Odoo, 2023
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:55+0000\n"
+"PO-Revision-Date: 2023-10-26 23:09+0000\n"
+"Last-Translator: Wil Odoo, 2023\n"
+"Language-Team: Chinese (Taiwan) (https://app.transifex.com/odoo/teams/41243/zh_TW/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: zh_TW\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: project_purchase
+#: model:ir.model.fields,field_description:project_purchase.field_project_project__purchase_orders_count
+msgid "# Purchase Orders"
+msgstr "採購訂單數目"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_project_project
+msgid "Project"
+msgstr "專案"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Order Items"
+msgstr "採購訂單項目"
+
+#. module: project_purchase
+#: model:ir.model,name:project_purchase.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "採購訂單資料行"
+
+#. module: project_purchase
+#. odoo-python
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#: code:addons/project_purchase/models/project_project.py:0
+#, python-format
+msgid "Purchase Orders"
+msgstr "採購訂單"
diff --git a/models/__init__.py b/models/__init__.py
new file mode 100644
index 0000000..a3c4a3f
--- /dev/null
+++ b/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import project_project
+from . import purchase_order_line
diff --git a/models/project_project.py b/models/project_project.py
new file mode 100644
index 0000000..93afb3c
--- /dev/null
+++ b/models/project_project.py
@@ -0,0 +1,176 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import json
+
+from odoo import api, fields, models, _, _lt
+from odoo.osv import expression
+from odoo.tools.misc import OrderedSet
+
+
+class Project(models.Model):
+ _inherit = "project.project"
+
+ purchase_orders_count = fields.Integer('# Purchase Orders', compute='_compute_purchase_orders_count', groups='purchase.group_purchase_user')
+
+ @api.depends('analytic_account_id')
+ def _compute_purchase_orders_count(self):
+ if not self.analytic_account_id:
+ self.purchase_orders_count = 0
+ return
+ query = self.env['purchase.order.line']._search([])
+ query.add_where('purchase_order_line.analytic_distribution ?| %s', [[str(account_id) for account_id in self.analytic_account_id.ids]])
+
+ query_string, query_param = query.select(
+ 'jsonb_object_keys(purchase_order_line.analytic_distribution) as account_id',
+ 'COUNT(DISTINCT(order_id)) as purchase_order_count',
+ )
+ query_string = f"{query_string} GROUP BY jsonb_object_keys(purchase_order_line.analytic_distribution)"
+
+ self._cr.execute(query_string, query_param)
+ data = {int(record.get('account_id')): record.get('purchase_order_count') for record in self._cr.dictfetchall()}
+ for project in self:
+ project.purchase_orders_count = data.get(project.analytic_account_id.id, 0)
+
+ # ----------------------------
+ # Actions
+ # ----------------------------
+
+ def action_open_project_purchase_orders(self):
+ query = self.env['purchase.order.line']._search([])
+ query.add_where('purchase_order_line.analytic_distribution ? %s', [str(self.analytic_account_id.id)])
+ query_string, query_param = query.select('order_id')
+ self._cr.execute(query_string, query_param)
+ purchase_order_ids = [pol.get('order_id') for pol in self._cr.dictfetchall()]
+ action_window = {
+ 'name': _('Purchase Orders'),
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'purchase.order',
+ 'views': [[False, 'tree'], [False, 'form']],
+ 'domain': [('id', 'in', purchase_order_ids)],
+ 'context': {
+ 'project_id': self.id,
+ }
+ }
+ if len(purchase_order_ids) == 1:
+ action_window['views'] = [[False, 'form']]
+ action_window['res_id'] = purchase_order_ids[0]
+ return action_window
+
+ def action_profitability_items(self, section_name, domain=None, res_id=False):
+ if section_name == 'purchase_order':
+ action = {
+ 'name': _('Purchase Order Items'),
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'purchase.order.line',
+ 'views': [[False, 'tree'], [False, 'form']],
+ 'domain': domain,
+ 'context': {
+ 'create': False,
+ 'edit': False,
+ },
+ }
+ if res_id:
+ action['res_id'] = res_id
+ if 'views' in action:
+ action['views'] = [
+ (view_id, view_type)
+ for view_id, view_type in action['views']
+ if view_type == 'form'
+ ] or [False, 'form']
+ action['view_mode'] = 'form'
+ return action
+ return super().action_profitability_items(section_name, domain, res_id)
+
+ # ----------------------------
+ # Project Updates
+ # ----------------------------
+
+ def _get_stat_buttons(self):
+ buttons = super(Project, self)._get_stat_buttons()
+ if self.user_has_groups('purchase.group_purchase_user'):
+ self_sudo = self.sudo()
+ buttons.append({
+ 'icon': 'credit-card',
+ 'text': _lt('Purchase Orders'),
+ 'number': self_sudo.purchase_orders_count,
+ 'action_type': 'object',
+ 'action': 'action_open_project_purchase_orders',
+ 'show': self_sudo.purchase_orders_count > 0,
+ 'sequence': 36,
+ })
+ return buttons
+
+ def _get_profitability_aal_domain(self):
+ return expression.AND([
+ super()._get_profitability_aal_domain(),
+ ['|', ('move_line_id', '=', False), ('move_line_id.purchase_line_id', '=', False)],
+ ])
+
+ def _add_purchase_items(self, profitability_items, with_action=True):
+ return False
+
+ def _get_profitability_labels(self):
+ labels = super()._get_profitability_labels()
+ labels['purchase_order'] = _lt('Purchase Orders')
+ return labels
+
+ def _get_profitability_sequence_per_invoice_type(self):
+ sequence_per_invoice_type = super()._get_profitability_sequence_per_invoice_type()
+ sequence_per_invoice_type['purchase_order'] = 10
+ return sequence_per_invoice_type
+
+ def _get_profitability_items(self, with_action=True):
+ profitability_items = super()._get_profitability_items(with_action)
+ if self.analytic_account_id:
+ query = self.env['purchase.order.line'].sudo()._search([
+ ('state', 'in', ['purchase', 'done']),
+ '|',
+ ('qty_invoiced', '>', 0),
+ '|', ('qty_to_invoice', '>', 0), ('product_uom_qty', '>', 0),
+ ], order=self.env['purchase.order.line']._order)
+ query.add_where('purchase_order_line.analytic_distribution ? %s', [str(self.analytic_account_id.id)])
+ query_string, query_param = query.select('"purchase_order_line".id', 'qty_invoiced', 'qty_to_invoice', 'product_uom_qty', 'price_unit', 'purchase_order_line.currency_id', '"purchase_order_line".analytic_distribution')
+ self._cr.execute(query_string, query_param)
+ purchase_order_line_read = [{
+ **pol,
+ 'invoice_lines': self.env['purchase.order.line'].browse(pol['id']).sudo().invoice_lines, # One2Many cannot be queried, they are not columns
+ } for pol in self._cr.dictfetchall()]
+ purchase_order_line_invoice_line_ids = self._get_already_included_profitability_invoice_line_ids()
+ with_action = with_action and self.user_has_groups('purchase.group_purchase_user, account.group_account_invoice, account.group_account_readonly')
+ if purchase_order_line_read:
+ currency_ids = OrderedSet(pol['currency_id'] for pol in purchase_order_line_read)
+
+ amount_invoiced = amount_to_invoice = 0.0
+ purchase_order_line_ids = []
+ for pol_read in purchase_order_line_read:
+ purchase_order_line_invoice_line_ids.extend(pol_read['invoice_lines'].ids)
+ currency = self.env['res.currency'].browse(pol_read['currency_id']).with_prefetch(currency_ids)
+ price_unit = currency._convert(pol_read['price_unit'], self.currency_id, self.company_id)
+ analytic_contribution = pol_read['analytic_distribution'][str(self.analytic_account_id.id)] / 100.
+ amount_invoiced -= price_unit * pol_read['qty_invoiced'] * analytic_contribution if pol_read['qty_invoiced'] > 0 else 0.0
+ if pol_read['qty_to_invoice'] > 0:
+ amount_to_invoice -= price_unit * pol_read['qty_to_invoice'] * analytic_contribution
+ else:
+ amount_to_invoice -= price_unit * (pol_read['product_uom_qty'] - pol_read['qty_invoiced']) * analytic_contribution
+ purchase_order_line_ids.append(pol_read['id'])
+ costs = profitability_items['costs']
+ section_id = 'purchase_order'
+ purchase_order_costs = {'id': section_id, 'sequence': self._get_profitability_sequence_per_invoice_type()[section_id], 'billed': amount_invoiced, 'to_bill': amount_to_invoice}
+ if with_action and purchase_order_line_ids:
+ args = [section_id, [('id', 'in', purchase_order_line_ids)]]
+ if len(purchase_order_line_ids) == 1:
+ args.append(purchase_order_line_ids[0])
+ action = {'name': 'action_profitability_items', 'type': 'object', 'args': json.dumps(args)}
+ purchase_order_costs['action'] = action
+ costs['data'].append(purchase_order_costs)
+ costs['total']['billed'] += amount_invoiced
+ costs['total']['to_bill'] += amount_to_invoice
+ domain = [
+ ('move_id.move_type', 'in', ['in_invoice', 'in_refund']),
+ ('parent_state', 'in', ['draft', 'posted']),
+ ('price_subtotal', '>', 0),
+ ('id', 'not in', purchase_order_line_invoice_line_ids),
+ ]
+ self._get_costs_items_from_purchase(domain, profitability_items, with_action=with_action)
+ return profitability_items
diff --git a/models/purchase_order_line.py b/models/purchase_order_line.py
new file mode 100644
index 0000000..deff88f
--- /dev/null
+++ b/models/purchase_order_line.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models
+
+
+class PurchaseOrderLine(models.Model):
+ _inherit = 'purchase.order.line'
+
+ def _compute_analytic_distribution(self):
+ super()._compute_analytic_distribution()
+ for line in self:
+ if line._context.get('project_id'):
+ line.analytic_distribution = {line.env['project.project'].browse(line._context['project_id']).analytic_account_id.id: 100}
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..4fa67e8
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_project_profitability
diff --git a/tests/test_project_profitability.py b/tests/test_project_profitability.py
new file mode 100644
index 0000000..0e6a65d
--- /dev/null
+++ b/tests/test_project_profitability.py
@@ -0,0 +1,509 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from datetime import datetime, timedelta
+
+from odoo import Command
+from odoo.tests import tagged
+
+from odoo.addons.project.tests.test_project_profitability import TestProjectProfitabilityCommon
+from odoo.addons.purchase.tests.test_purchase_invoice import TestPurchaseToInvoiceCommon
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo.tools.float_utils import float_compare
+
+
+@tagged('-at_install', 'post_install')
+class TestProjectPurchaseProfitability(TestProjectProfitabilityCommon, TestPurchaseToInvoiceCommon, AccountTestInvoicingCommon):
+
+ def test_bills_without_purchase_order_are_accounted_in_profitability_project_purchase(self):
+ """
+ A bill that has an AAL on one of its line should be taken into account
+ for the profitability of the project.
+ The contribution of the line should only be dependent
+ on the project's analytic account % that was set on the line
+ """
+ # a custom analytic contribution (number between 1 -> 100 included)
+ analytic_distribution = 42
+ analytic_contribution = analytic_distribution / 100.
+ # create a bill_1 with the AAL
+ bill_1 = self.env['account.move'].create({
+ "name": "Bill_1 name",
+ "move_type": "in_invoice",
+ "state": "draft",
+ "partner_id": self.partner.id,
+ "invoice_date": datetime.today(),
+ "invoice_line_ids": [Command.create({
+ "analytic_distribution": {self.analytic_account.id: analytic_distribution},
+ "product_id": self.product_a.id,
+ "quantity": 1,
+ "product_uom_id": self.product_a.uom_id.id,
+ "price_unit": self.product_a.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ })],
+ })
+ # add 2 new AAL to the analytic account. Those costs must be present in the cost data
+ self.env['account.analytic.line'].create([{
+ 'name': 'extra costs 1',
+ 'account_id': self.analytic_account.id,
+ 'amount': -50,
+ }, {
+ 'name': 'extra costs 2',
+ 'account_id': self.analytic_account.id,
+ 'amount': -100,
+ }])
+ # the bill_1 is in draft, therefore it should have the cost "to_bill" same as the -product_price (untaxed)
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'other_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_costs'],
+ 'to_bill': 0.0,
+ 'billed': -150.0,
+ }, {
+ 'id': 'other_purchase_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'],
+ 'to_bill': -self.product_a.standard_price * analytic_contribution,
+ 'billed': 0.0,
+ }],
+ 'total': {'to_bill': -self.product_a.standard_price * analytic_contribution, 'billed': -150.0},
+ },
+ )
+ # post bill_1
+ bill_1.action_post()
+ # we posted the bill_1, therefore the cost "billed" should be -product_price, to_bill should be back to 0
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'other_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_costs'],
+ 'to_bill': 0.0,
+ 'billed': -150.0,
+ }, {
+ 'id': 'other_purchase_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'],
+ 'to_bill': 0.0,
+ 'billed': -self.product_a.standard_price * analytic_contribution,
+ }],
+ 'total': {'to_bill': 0.0, 'billed': -self.product_a.standard_price * analytic_contribution - 150},
+ },
+ )
+ # create another bill, with 2 lines, 2 diff products, the second line has 2 as quantity
+ bill_2 = self.env['account.move'].create({
+ "name": "I have 2 lines",
+ "move_type": "in_invoice",
+ "state": "draft",
+ "partner_id": self.partner.id,
+ "invoice_date": datetime.today(),
+ "invoice_line_ids": [Command.create({
+ "analytic_distribution": {self.analytic_account.id: analytic_distribution},
+ "product_id": self.product_a.id,
+ "quantity": 1,
+ "product_uom_id": self.product_a.uom_id.id,
+ "price_unit": self.product_a.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ }), Command.create({
+ "analytic_distribution": {self.analytic_account.id: analytic_distribution},
+ "product_id": self.product_b.id,
+ "quantity": 2,
+ "product_uom_id": self.product_b.uom_id.id,
+ "price_unit": self.product_b.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ })],
+ })
+ # bill_2 is not posted, therefore its cost should be "to_billed" = - sum of all product_price * qty for each line
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'other_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_costs'],
+ 'to_bill': 0.0,
+ 'billed': -150.0,
+ }, {
+ 'id': 'other_purchase_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'],
+ 'to_bill': -(self.product_a.standard_price + 2 * self.product_b.standard_price) * analytic_contribution,
+ 'billed': -self.product_a.standard_price * analytic_contribution,
+ }],
+ 'total': {
+ 'to_bill': -(self.product_a.standard_price + 2 * self.product_b.standard_price) * analytic_contribution,
+ 'billed': -self.product_a.standard_price * analytic_contribution - 150,
+ },
+ },
+ )
+ # post bill_2
+ bill_2.action_post()
+ # bill_2 is posted, therefore its cost should be counting in "billed", with the cost of bill_1
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'other_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_costs'],
+ 'to_bill': 0.0,
+ 'billed': -150.0,
+ }, {
+ 'id': 'other_purchase_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'],
+ 'to_bill': 0.0,
+ 'billed': -2 * (self.product_a.standard_price + self.product_b.standard_price) * analytic_contribution,
+ }],
+ 'total': {
+ 'to_bill': 0.0,
+ 'billed': -2 * (self.product_a.standard_price + self.product_b.standard_price) * analytic_contribution - 150,
+ },
+ },
+ )
+ # create a new purchase order
+ purchase_order = self.env['purchase.order'].create({
+ "name": "A purchase order",
+ "partner_id": self.partner_a.id,
+ "order_line": [Command.create({
+ "analytic_distribution": {self.analytic_account.id: analytic_distribution},
+ "product_id": self.product_order.id,
+ "product_qty": 1,
+ "price_unit": self.product_order.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ })],
+ })
+ purchase_order.button_confirm()
+ # we should have a new section "purchase_order", the total should be updated,
+ # but the "other_purchase_costs" shouldn't change, as we don't take into
+ # account bills from purchase orders, as those are already taken into calculations
+ # from the purchase orders (in "purchase_order" section)
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'other_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_costs'],
+ 'to_bill': 0.0,
+ 'billed': -150.0,
+ }, {
+ 'id': 'purchase_order',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['purchase_order'],
+ 'to_bill': -self.product_order.standard_price * analytic_contribution,
+ 'billed': 0.0,
+ }, {
+ 'id': 'other_purchase_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'],
+ 'to_bill': 0.0,
+ 'billed': -2 * (self.product_a.standard_price + self.product_b.standard_price) * analytic_contribution,
+ }],
+ 'total': {
+ 'to_bill': -self.product_order.standard_price * analytic_contribution,
+ 'billed': -2 * (self.product_a.standard_price + self.product_b.standard_price) * analytic_contribution - 150,
+ },
+ },
+ )
+ self._create_invoice_for_po(purchase_order)
+ # now the bill has been posted, its costs should be accounted in the "billed" part
+ # of the purchase_order section, but should touch in the other_purchase_costs
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'other_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_costs'],
+ 'to_bill': 0.0,
+ 'billed': -150.0,
+ }, {
+ 'id': 'purchase_order',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['purchase_order'],
+ 'to_bill': 0.0,
+ 'billed': -self.product_order.standard_price * analytic_contribution,
+ }, {
+ 'id': 'other_purchase_costs',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'],
+ 'to_bill': 0.0,
+ 'billed': -2 * (self.product_a.standard_price + self.product_b.standard_price) * analytic_contribution,
+ }],
+ 'total': {
+ 'to_bill': 0.0,
+ 'billed': -(2 * self.product_a.standard_price +
+ 2 * self.product_b.standard_price +
+ self.product_order.standard_price) * analytic_contribution - 150,
+ },
+ },
+ )
+
+ def test_account_analytic_distribution_ratio(self):
+ """
+ When adding multiple account analytics on a purchase line, and one of those
+ is from a project (for ex: project created on confirmed SO),
+ then in the profitability only the corresponding ratio of the analytic distribution
+ for that project analytic account should be taken into account.
+ (for ex: if there are 2 accounts on 1 line, one is 60% project analytic account, 40% some other,
+ then the profitability should only reflect 60% of the cost of the line, not 100%)
+ """
+ # define the ratios for the analytic account of the line
+ analytic_ratios = {
+ "project_ratio": 60,
+ "other_ratio": 40,
+ }
+ self.assertEqual(sum(ratio for ratio in analytic_ratios.values()), 100)
+ # create another analytic_account that is not really relevant
+ other_analytic_account = self.env['account.analytic.account'].create({
+ 'name': 'Not important',
+ 'code': 'KO-1234',
+ 'plan_id': self.analytic_plan.id,
+ })
+ # create a new purchase order
+ purchase_order = self.env['purchase.order'].create({
+ "name": "A purchase order",
+ "partner_id": self.partner_a.id,
+ "order_line": [Command.create({
+ "analytic_distribution": {
+ # this is the analytic_account that is linked to the project
+ self.analytic_account.id: analytic_ratios["project_ratio"],
+ other_analytic_account.id: analytic_ratios["other_ratio"],
+ },
+ "product_id": self.product_order.id,
+ "product_qty": 1,
+ "price_unit": self.product_order.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ })],
+ })
+ purchase_order.button_confirm()
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'purchase_order',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['purchase_order'],
+ 'to_bill': -(self.product_order.standard_price * (analytic_ratios["project_ratio"] / 100)),
+ 'billed': 0.0,
+ }],
+ 'total': {
+ 'to_bill': -(self.product_order.standard_price * (analytic_ratios["project_ratio"] / 100)),
+ 'billed': 0.0,
+ },
+ },
+ )
+ self._create_invoice_for_po(purchase_order)
+ self.assertDictEqual(
+ self.project._get_profitability_items(False)['costs'],
+ {
+ 'data': [{
+ 'id': 'purchase_order',
+ 'sequence': self.project._get_profitability_sequence_per_invoice_type()['purchase_order'],
+ 'to_bill': 0.0,
+ 'billed': -(self.product_order.standard_price * (analytic_ratios["project_ratio"] / 100)),
+ }],
+ 'total': {
+ 'to_bill': 0.0,
+ 'billed': -(self.product_order.standard_price * (analytic_ratios["project_ratio"] / 100)),
+ },
+ },
+ )
+
+ def test_multi_currency_for_project_purchase_profitability(self):
+ """ This test ensures that when purchase orders with different currencies are linked to the same project, the amount are correctly computed according to the
+ rate of the company """
+ project = self.env['project.project'].create({'name': 'new project'})
+ project._create_analytic_account()
+ account = project.analytic_account_id
+ foreign_company = self.company_data_2['company']
+ foreign_company.currency_id = self.foreign_currency
+
+ # a custom analytic contribution (number between 1 -> 100 included)
+ analytic_distribution = 42
+ analytic_contribution = analytic_distribution / 100.
+ # Create a bill_1 with the foreign_currency.
+ bill_1 = self.env['account.move'].create({
+ "name": "Bill foreign currency",
+ "move_type": "in_invoice",
+ "state": "draft",
+ "partner_id": self.partner.id,
+ "invoice_date": datetime.today(),
+ "date": datetime.today(),
+ "invoice_date_due": datetime.today() - timedelta(days=1),
+ "company_id": foreign_company.id,
+ "invoice_line_ids": [Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_a.id,
+ "quantity": 1,
+ "product_uom_id": self.product_a.uom_id.id,
+ "price_unit": self.product_a.standard_price,
+ "currency_id": self.foreign_currency.id,
+ }), Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_a.id,
+ "quantity": 2,
+ "product_uom_id": self.product_a.uom_id.id,
+ "price_unit": self.product_a.standard_price,
+ "currency_id": self.foreign_currency.id,
+ })],
+ })
+ # Ensures that if no items have the main currency, the total is still displayed in the main currency.
+ # Expected total : product_price * 0.2 (rate) * 3 (number of products).
+ # Note : for some reason, the method to round the amount to the rounding of the currency is not 100% reliable.
+ # We use a float_compare in order to ensure the value is close enough to the expected result. This problem has no repercusion on the client side, since
+ # there is also a rounding method on this side to ensure the amount is correctly displayed.
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('other_purchase_costs', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][0]['sequence'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 0.6, items['data'][0]['to_bill'], 2), 0)
+ self.assertEqual(0.0, items['data'][0]['billed'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 0.6, items['total']['to_bill'], 2), 0)
+ self.assertEqual(0.0, items['total']['billed'])
+
+ # Create a bill 2 with the main currency.
+ bill_2 = self.env['account.move'].create({
+ "name": "Bill main currency",
+ "move_type": "in_invoice",
+ "state": "draft",
+ "partner_id": self.partner.id,
+ "invoice_date": datetime.today(),
+ "invoice_line_ids": [Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_a.id,
+ "quantity": 1,
+ "product_uom_id": self.product_a.uom_id.id,
+ "price_unit": self.product_a.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ }), Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_a.id,
+ "quantity": 2,
+ "product_uom_id": self.product_a.uom_id.id,
+ "price_unit": self.product_a.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ })],
+ })
+
+ # The 2 bills are in draft, therefore the "to_bill" section should contain the total cost of the 2 bills.
+ # The expected total is therefore product_price * 1 * 3 + product_price * 0.2 * 3 => * 3.6
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('other_purchase_costs', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][0]['sequence'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['data'][0]['to_bill'], 2), 0)
+ self.assertEqual(0.0, items['data'][0]['billed'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['total']['to_bill'], 2), 0)
+ self.assertEqual(0.0, items['total']['billed'])
+
+ # Bill 2 is posted. Its total is now in the 'billed' section, while the bill_1 is still in the 'to bill' one.
+ bill_2.action_post()
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('other_purchase_costs', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][0]['sequence'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 0.6, items['data'][0]['to_bill'], 2), 0)
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3, items['data'][0]['billed'], 2), 0)
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 0.6, items['total']['to_bill'], 2), 0)
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3, items['total']['billed'], 2), 0)
+
+ # Bill 1 is posted. Its total is now in the 'billed' section, the 'to bill' one should now be empty.
+ bill_1.action_post()
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('other_purchase_costs', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][0]['sequence'])
+ self.assertEqual(0.0, items['data'][0]['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['data'][0]['billed'], 2), 0)
+ self.assertEqual(0.0, items['total']['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['total']['billed'], 2), 0)
+
+ # create a new purchase order with the foreign company
+ purchase_order_foreign = self.env['purchase.order'].create({
+ "name": "A foreign purchase order",
+ "partner_id": self.partner_a.id,
+ "company_id": foreign_company.id,
+ "order_line": [Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_order.id,
+ "product_qty": 1,
+ "price_unit": self.product_order.standard_price,
+ "currency_id": self.foreign_currency.id,
+ }), Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_order.id,
+ "product_qty": 2,
+ "price_unit": self.product_order.standard_price,
+ "currency_id": self.foreign_currency.id,
+ })],
+ })
+ purchase_order_foreign.button_confirm()
+
+ # We should have a new section "purchase_order", the total should be updated,
+ # but the "other_purchase_costs" shouldn't change, as we don't take into
+ # account bills from purchase orders in this section.
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('purchase_order', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['purchase_order'], items['data'][0]['sequence'])
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 0.6, items['data'][0]['to_bill'], 2), 0)
+ self.assertEqual(0.0, items['data'][0]['billed'])
+ self.assertEqual('other_purchase_costs', items['data'][1]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][1]['sequence'])
+ self.assertEqual(0.0, items['data'][1]['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['data'][1]['billed'], 2), 0)
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 0.6, items['total']['to_bill'], 2), 0)
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['total']['billed'], 2), 0)
+
+ # create a new purchase order
+ purchase_order = self.env['purchase.order'].create({
+ "name": "A foreign purchase order",
+ "partner_id": self.partner_a.id,
+ "company_id": self.env.company.id,
+ "order_line": [Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_order.id,
+ "product_qty": 1,
+ "price_unit": self.product_order.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ }), Command.create({
+ "analytic_distribution": {account.id: analytic_distribution},
+ "product_id": self.product_order.id,
+ "product_qty": 2,
+ "price_unit": self.product_order.standard_price,
+ "currency_id": self.env.company.currency_id.id,
+ })],
+ })
+ purchase_order.button_confirm()
+ # The 'to bill' section should be updated in the 'total' and 'purchase orders' sections.
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('purchase_order', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['purchase_order'], items['data'][0]['sequence'])
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 3.6, items['data'][0]['to_bill'], 2), 0)
+ self.assertEqual(0.0, items['data'][0]['billed'])
+ self.assertEqual('other_purchase_costs', items['data'][1]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][1]['sequence'])
+ self.assertEqual(0.0, items['data'][1]['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['data'][1]['billed'], 2), 0)
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 3.6, items['total']['to_bill'], 2), 0)
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['total']['billed'], 2), 0)
+
+ self._create_invoice_for_po(purchase_order)
+ # The purchase order of the main company has been billed. Its total should now be in the 'billed' section.
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('purchase_order', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['purchase_order'], items['data'][0]['sequence'])
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 0.6, items['data'][0]['to_bill'], 2), 0)
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 3, items['data'][0]['billed'], 2), 0)
+ self.assertEqual('other_purchase_costs', items['data'][1]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][1]['sequence'])
+ self.assertEqual(0.0, items['data'][1]['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['data'][1]['billed'], 2), 0)
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 0.6, items['total']['to_bill'], 2), 0)
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6 - self.product_order.standard_price * analytic_contribution * 3, items['total']['billed'], 2), 0)
+
+ self._create_invoice_for_po(purchase_order_foreign)
+ # The purchase order of the main company has been billed. Its total should now be in the 'billed' section.
+ # The 'to bill' section of the purchase order should now be empty
+ items = project._get_profitability_items(with_action=False)['costs']
+ self.assertEqual('purchase_order', items['data'][0]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['purchase_order'], items['data'][0]['sequence'])
+ self.assertEqual(0.0, items['data'][0]['to_bill'])
+ self.assertEqual(float_compare(-self.product_order.standard_price * analytic_contribution * 3.6, items['data'][0]['billed'], 2), 0)
+ self.assertEqual('other_purchase_costs', items['data'][1]['id'])
+ self.assertEqual(project._get_profitability_sequence_per_invoice_type()['other_purchase_costs'], items['data'][1]['sequence'])
+ self.assertEqual(0.0, items['data'][1]['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6, items['data'][1]['billed'], 2), 0)
+ self.assertEqual(0.0, items['total']['to_bill'])
+ self.assertEqual(float_compare(-self.product_a.standard_price * analytic_contribution * 3.6 - self.product_order.standard_price * analytic_contribution * 3.6, items['total']['billed'], 2), 0)
+
+ def _create_invoice_for_po(self, purchase_order):
+ purchase_order.action_create_invoice()
+ purchase_bill = purchase_order.invoice_ids # get the bill from the purchase
+ purchase_bill.invoice_date = datetime.today()
+ purchase_bill.action_post()