diff --git a/modules/project/CHANGELOG b/modules/project/CHANGELOG
index e4743c75d8..092fdb11d5 100644
--- a/modules/project/CHANGELOG
+++ b/modules/project/CHANGELOG
@@ -1,3 +1,4 @@
+* Add origin reference to work
* Add number to the work efforts
* Add support for Python 3.14
* Remove support for Python 3.9
diff --git a/modules/project/view/work_form.xml b/modules/project/view/work_form.xml
index 79881fc924..f45ca232d3 100644
--- a/modules/project/view/work_form.xml
+++ b/modules/project/view/work_form.xml
@@ -29,6 +29,8 @@ this repository contains the full copyright notices and license terms. -->
+
+
diff --git a/modules/project/view/work_list.xml b/modules/project/view/work_list.xml
index a8949af3a1..7a5949e41a 100644
--- a/modules/project/view/work_list.xml
+++ b/modules/project/view/work_list.xml
@@ -3,6 +3,7 @@
this repository contains the full copyright notices and license terms. -->
+
diff --git a/modules/project/view/work_list_children.xml b/modules/project/view/work_list_children.xml
index f77864be7a..a56939bbc7 100644
--- a/modules/project/view/work_list_children.xml
+++ b/modules/project/view/work_list_children.xml
@@ -2,6 +2,7 @@
+
diff --git a/modules/project/view/work_list_simple.xml b/modules/project/view/work_list_simple.xml
index c4734be177..80f72e978d 100644
--- a/modules/project/view/work_list_simple.xml
+++ b/modules/project/view/work_list_simple.xml
@@ -3,6 +3,7 @@
this repository contains the full copyright notices and license terms. -->
+
diff --git a/modules/project/view/work_tree.xml b/modules/project/view/work_tree.xml
index 07b106336f..a6f24a24ae 100644
--- a/modules/project/view/work_tree.xml
+++ b/modules/project/view/work_tree.xml
@@ -6,6 +6,7 @@ this repository contains the full copyright notices and license terms. -->
+
diff --git a/modules/project/view/work_tree_simple.xml b/modules/project/view/work_tree_simple.xml
index 43e792e933..4c3a091aea 100644
--- a/modules/project/view/work_tree_simple.xml
+++ b/modules/project/view/work_tree_simple.xml
@@ -6,6 +6,7 @@ this repository contains the full copyright notices and license terms. -->
+
diff --git a/modules/project/work.py b/modules/project/work.py
index fec3dce22c..1318739fb1 100644
--- a/modules/project/work.py
+++ b/modules/project/work.py
@@ -152,8 +152,17 @@ class Work(
('project', 'Project'),
('task', 'Task')
],
- "Type", required=True)
- company = fields.Many2One('company.company', "Company", required=True)
+ "Type", required=True,
+ domain=[
+ If(Eval('origin', None),
+ ('type', '=', 'task'),
+ ()),
+ ])
+ company = fields.Many2One(
+ 'company.company', "Company", required=True,
+ states={
+ 'readonly': Bool(Eval('origin', None)),
+ })
number = fields.Char("Number", readonly=True)
party = fields.Many2One('party.party', 'Party',
states={
@@ -168,6 +177,9 @@ class Work(
states={
'invisible': Eval('type') != 'project',
})
+ origin = fields.Reference(
+ "Origin", selection='get_origins',
+ help="The source of the task.")
timesheet_works = fields.One2Many(
'timesheet.work', 'origin', 'Timesheet Works', readonly=True, size=1)
timesheet_available = fields.Function(fields.Boolean(
@@ -260,6 +272,17 @@ class Work(
def default_company(cls):
return Transaction().context.get('company')
+ @classmethod
+ def _get_origins(cls):
+ return []
+
+ @classmethod
+ def get_origins(cls):
+ IrModel = Pool().get('ir.model')
+ get_name = IrModel.get_name
+ models = cls._get_origins()
+ return [(None, '')] + [(m, get_name(m)) for m in models]
+
@classmethod
def default_status(cls):
pool = Pool()
diff --git a/modules/project_revenue/work.py b/modules/project_revenue/work.py
index 55ca6a415e..a2a935a65d 100644
--- a/modules/project_revenue/work.py
+++ b/modules/project_revenue/work.py
@@ -12,7 +12,7 @@ from trytond.model import fields
from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool, PoolMeta
-from trytond.pyson import Eval
+from trytond.pyson import Bool, Eval, If
from trytond.transaction import Transaction
@@ -21,7 +21,13 @@ class Work(metaclass=PoolMeta):
product = fields.Many2One('product.product', 'Product',
domain=[
('type', '=', 'service'),
+ If(Eval('origin', None),
+ ('id', '=', -1),
+ ()),
],
+ states={
+ 'invisible': Bool(Eval('origin', None)),
+ },
context={
'company': Eval('company', -1),
},