diff --git a/modules/production_work/CHANGELOG b/modules/production_work/CHANGELOG
index cd7469e52f..56c1378102 100644
--- a/modules/production_work/CHANGELOG
+++ b/modules/production_work/CHANGELOG
@@ -1,3 +1,4 @@
+* Add employee on cycles for running and done states
* Display cost of works
Version 6.8.0 - 2023-05-01
diff --git a/modules/production_work/tests/scenario_production_work.rst b/modules/production_work/tests/scenario_production_work.rst
index e0c7c9043a..f5f184fca1 100644
--- a/modules/production_work/tests/scenario_production_work.rst
+++ b/modules/production_work/tests/scenario_production_work.rst
@@ -7,7 +7,7 @@ Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
- >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.tests.tools import activate_modules, set_user
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
@@ -17,6 +17,11 @@ Activate modules::
>>> config = activate_modules('production_work')
+ >>> Employee = Model.get('company.employee')
+ >>> Group = Model.get('res.group')
+ >>> Party = Model.get('party.party')
+ >>> User = Model.get('res.user')
+
Create company::
>>> _ = create_company()
@@ -145,6 +150,24 @@ Create an Inventory::
>>> inventory.state
'done'
+Create production user::
+
+ >>> production_user = User()
+ >>> production_user.name = "Production"
+ >>> production_user.login = 'production'
+ >>> production_user.groups.extend(Group.find([
+ ... ('name', '=', 'Production'),
+ ... ]))
+ >>> employee_party = Party(name="Employee")
+ >>> employee_party.save()
+ >>> employee = Employee(party=employee_party)
+ >>> employee.save()
+ >>> production_user.employees.append(employee)
+ >>> production_user.employee = employee
+ >>> production_user.save()
+
+ >>> set_user(production_user)
+
Make a production::
>>> Production = Model.get('production')
@@ -197,17 +220,23 @@ Run works::
>>> cycle1.click('run')
>>> cycle1.state
'running'
+ >>> cycle1.run_by == employee
+ True
>>> work1.reload()
>>> work1.state
'running'
>>> cycle1.click('do')
>>> cycle1.state
'done'
+ >>> cycle1.done_by == employee
+ True
>>> work1.reload()
>>> work1.state
'finished'
>>> cycle2 = work2.cycles.new()
>>> cycle2.click('cancel')
+ >>> cycle2.cancelled_by == employee
+ True
>>> cycle2.state
'cancelled'
>>> work2.reload()
diff --git a/modules/production_work/view/work_cycle_form.xml b/modules/production_work/view/work_cycle_form.xml
index 5a573aab82..a78505c91e 100644
--- a/modules/production_work/view/work_cycle_form.xml
+++ b/modules/production_work/view/work_cycle_form.xml
@@ -7,6 +7,10 @@ this repository contains the full copyright notices and license terms. -->
+
+
+
+
diff --git a/modules/production_work/work.py b/modules/production_work/work.py
index 8870f310f9..8a38666398 100644
--- a/modules/production_work/work.py
+++ b/modules/production_work/work.py
@@ -14,6 +14,7 @@ from trytond.model import (
DeactivableMixin, Index, ModelSQL, ModelView, Workflow, fields,
sequence_ordered, tree)
from trytond.model.exceptions import AccessError
+from trytond.modules.company.model import employee_field, set_employee
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If, TimeDelta
@@ -321,6 +322,18 @@ class WorkCycle(Workflow, ModelSQL, ModelView):
'readonly': Eval('state').in_(['done', 'draft', 'cancelled']),
})
cost = fields.Numeric('Cost', digits=price_digits, readonly=True)
+ company = fields.Function(
+ fields.Many2One('company.company', "Company"),
+ 'on_change_with_company', searcher='search_company')
+ run_by = employee_field("Run By", states={
+ 'readonly': Eval('state') != 'draft',
+ })
+ done_by = employee_field("Done By", states={
+ 'readonly': Eval('state').in_(['draft', 'running']),
+ })
+ cancelled_by = employee_field("Cancelled By", states={
+ 'readonly': Eval('state').in_(['draft', 'running']),
+ })
state = fields.Selection([
('draft', 'Draft'),
('running', 'Running'),
@@ -361,10 +374,28 @@ class WorkCycle(Workflow, ModelSQL, ModelView):
def default_state(cls):
return 'draft'
+ @fields.depends('work', '_parent_work.company')
+ def on_change_with_company(self, name=None):
+ if self.work and self.work.company:
+ return self.work.company.id
+
+ @classmethod
+ def search_company(cls, name, clause):
+ return [('work.' + clause[0], *clause[1:])]
+
+ @classmethod
+ def copy(cls, cycles, default=None):
+ default = default.copy() if default is not None else {}
+ default.setdefault('run_by')
+ default.setdefault('done_by')
+ default.setdefault('cancelled_by')
+ return super().copy(cycles, default=default)
+
@classmethod
@ModelView.button
@set_work_state
@Workflow.transition('cancelled')
+ @set_employee('cancelled_by')
def cancel(cls, cycles):
pass
@@ -372,6 +403,7 @@ class WorkCycle(Workflow, ModelSQL, ModelView):
@ModelView.button
@set_work_state
@Workflow.transition('running')
+ @set_employee('run_by')
def run(cls, cycles):
pass
@@ -379,6 +411,7 @@ class WorkCycle(Workflow, ModelSQL, ModelView):
@ModelView.button
@set_work_state
@Workflow.transition('done')
+ @set_employee('done_by')
def do(cls, cycles):
now = datetime.datetime.now()
for cycle in cycles:
diff --git a/modules/production_work/work.xml b/modules/production_work/work.xml
index defa6075d7..e34680b1bc 100644
--- a/modules/production_work/work.xml
+++ b/modules/production_work/work.xml
@@ -331,7 +331,7 @@ this repository contains the full copyright notices and license terms. -->