Simplify workflow engine

- Remove workflow module
- Add ir.model.button for access rights

review256001
This commit is contained in:
Cédric Krier
2012-03-25 00:15:17 +01:00
parent 2f0d152ff7
commit be0e5c54a9
54 changed files with 460 additions and 4915 deletions
+3
View File
@@ -1,3 +1,6 @@
* Remove workflow module
* Simplify workflow engine
* Add ir.model.button for access rights
* Replace fill by expand
* Integer, Numeric and Float allow None as value
* NULL value is None and not False
-2
View File
@@ -22,5 +22,3 @@ include trytond/res/locale/*.po
include trytond/test/*.xml
include trytond/webdav/*.xml
include trytond/webdav/locale/*.po
include trytond/workflow/*.xml
include trytond/workflow/locale/*.po
-2
View File
@@ -1,8 +1,6 @@
- Add check on action groups when executing wizard
- Handle button as a field to allow to override it with python code
- Allow to create fields from the client interface
- Improve encoding of default properties
- Use determined action name in workflow like for default value
- Add check for index and constraint name lenght (limit 31)
- Change _constraint to pass a BrowseRecordList instead of a list of ids
- Add order attribute on page tag
+28 -20
View File
@@ -103,6 +103,20 @@ ModelView
It adds requirements to display a view of the model in the client.
Class attributes:
.. attribute:: ModelView._buttons
It contains a dictionary with button name as key and the states dictionary
for the button. This states dictionary will be used to generate the views
containing the button.
Static methods:
.. staticmethod:: ModelView.button
Decorate button method to check group access.
Instance methods:
.. method:: ModelView.fields_view_get([view_id[, view_type[, toolbar[, hexmd5]]]])
@@ -297,11 +311,6 @@ Instance methods:
Helper method that checks if there is no recursion in the tree composed
with ``parent`` as parent field name.
.. method:: ModelStorage.workflow_trigger_trigger(ids)
Trigger a trigger event on the :ref:`workflow <topics-workflow>` of
records.
========
ModelSQL
========
@@ -378,31 +387,30 @@ Instance methods:
- a list of arguments for the tables
=============
ModelWorkflow
=============
========
Workflow
========
.. class:: ModelWorkflow
.. class:: Workflow
It adds workflow capability to :class:`ModelStorage`.
A Mix-in class to handle transition check.
Instance methods:
Class attribute:
.. method:: ModelWorkflow.workflow_trigger_create(ids)
.. attribute:: Workflow._transition_state
Trigger create event on the :ref:`workflow <topics-workflow>` of records.
The name of the field that will be used to check state transition.
.. method:: ModelWorkflow.workflow_trigger_write(ids)
.. attribute:: Workflow._transitions
Trigger write event on the :ref:`workflow <topics-workflow>` of records.
A set containing tuples of from and to state.
.. method:: ModelWorkflow.workflow_trigger_validate(ids)
Static methods:
Trigger validate event on the :ref:`workflow <topics-workflow>` of records.
.. staticmethod:: Workflow.transition(state)
.. method:: ModelWorkflow.workflow_trigger_delete(ids)
Trigger delete event on the :ref:`workflow <topics-workflow>` of records.
Decorate method to filter ids for which the transition is valid and finally
to update the state of the filtered ids.
==============
ModelSingleton
+1 -1
View File
@@ -6,7 +6,7 @@ Modules
The modules of Tryton extend the functionality of the platform. The server
comes by default with only a basic functionality included in these modules:
``ir``, ``res``, ``webdav``, ``workflow``.
``ir``, ``res``, ``webdav``.
Module Structure
================
+2 -5
View File
@@ -273,14 +273,11 @@ Display a button.
* ``string``: The string that will be displayed inside the button.
* ``type``: It can be ``workflow``, ``object`` or ``action``. The default
is ``workflow``. It defines which type of action must be run when
clicking on it.
* ``type``: It can be ``object`` or ``action``. The default is ``object``.
It defines which type of action must be run when clicking on it.
* ``name``: The name of the action:
* ``workflow``: the name of the signal that will be sent.
* ``object``: the name of the function that will called. The function
must have this syntax:
-1
View File
@@ -31,7 +31,6 @@ setup(name=PACKAGE,
'trytond.ir.ui': ['*.xml', '*.rng', '*.rnc'],
'trytond.res': ['*.xml', 'locale/*.po'],
'trytond.webdav': ['*.xml', 'locale/*.po'],
'trytond.workflow': ['*.xml', 'locale/*.po'],
'trytond.test': ['*.xml'],
},
scripts=['bin/trytond'],
+1 -7
View File
@@ -177,7 +177,7 @@ class Database(DatabaseInterface):
if (len(line)>0) and (not line.isspace()):
cursor.execute(line)
for i in ('ir', 'workflow', 'res', 'webdav'):
for i in ('ir', 'res', 'webdav'):
root_path = os.path.join(os.path.dirname(__file__), '..', '..')
tryton_file = os.path.join(root_path, i, '__tryton__.py')
with open(tryton_file) as fp:
@@ -297,12 +297,6 @@ class Cursor(CursorInterface):
'ir_ui_menu',
'res_user',
'res_group',
'wkf',
'wkf_activity',
'wkf_transition',
'wkf_instance',
'wkf_workitem',
'wkf_witm_trans',
'ir_module_module',
'ir_module_module_dependency',
'ir_translation',
-69
View File
@@ -91,75 +91,6 @@ CREATE TABLE `res_user-res_group` (
CONSTRAINT `res_user-res_group_group_fkey` FOREIGN KEY (`group`) REFERENCES res_group (id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE wkf (
id BIGINT AUTO_INCREMENT NOT NULL,
name VARCHAR(255),
model VARCHAR(255),
on_create BOOLEAN NOT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB;
CREATE TABLE wkf_activity (
id BIGINT AUTO_INCREMENT NOT NULL,
workflow BIGINT,
subflow BIGINT,
split_mode VARCHAR(255),
join_mode VARCHAR(255),
name VARCHAR(255),
signal_send VARCHAR(255),
flow_start BOOLEAN NOT NULL,
flow_stop BOOLEAN NOT NULL,
stop_other BOOLEAN NOT NULL,
action VARCHAR(255),
PRIMARY KEY(id),
CONSTRAINT wkf_activity_workflow_fkey FOREIGN KEY (workflow) REFERENCES wkf (id) ON DELETE CASCADE,
CONSTRAINT wkf_activity_subflow_fkey FOREIGN KEY (subflow) REFERENCES wkf (id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE TABLE wkf_transition (
id BIGINT AUTO_INCREMENT NOT NULL,
act_from BIGINT,
act_to BIGINT,
`condition` VARCHAR(255),
trigger_expr_id VARCHAR(255),
`signal` VARCHAR(255),
`group` BIGINT,
PRIMARY KEY(id),
CONSTRAINT wkf_transition_act_from_fkey FOREIGN KEY (act_from) REFERENCES wkf_activity (id) ON DELETE CASCADE,
CONSTRAINT wkf_transition_act_to_fkey FOREIGN KEY (act_to) REFERENCES wkf_activity (id) ON DELETE CASCADE,
CONSTRAINT wkf_transition_group_fkey FOREIGN KEY (`group`) REFERENCES res_group (id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE TABLE wkf_instance (
id BIGINT AUTO_INCREMENT NOT NULL,
workflow BIGINT,
uid BIGINT DEFAULT 0,
res_id BIGINT NOT NULL DEFAULT 0,
res_type VARCHAR(255) NOT NULL,
state VARCHAR(255) NOT NULL,
PRIMARY KEY(id),
CONSTRAINT wkf_instance_workflow_fkey FOREIGN KEY (workflow) REFERENCES wkf (id) ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE TABLE wkf_workitem (
id BIGINT AUTO_INCREMENT NOT NULL,
activity BIGINT,
instance BIGINT,
subflow BIGINT,
state VARCHAR(255),
PRIMARY KEY(id),
CONSTRAINT wkf_workitem_activity_fkey FOREIGN KEY (activity) REFERENCES wkf_activity (id) ON DELETE CASCADE,
CONSTRAINT wkf_workitem_instance_fkey FOREIGN KEY (instance) REFERENCES wkf_instance (id) ON DELETE CASCADE,
CONSTRAINT wkf_workitem_subflow_fkey FOREIGN KEY (subflow) REFERENCES wkf_instance (id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE wkf_witm_trans (
trans_id BIGINT,
inst_id BIGINT,
CONSTRAINT wkf_witm_trans_trans_id_fkey FOREIGN KEY (trans_id) REFERENCES wkf_transition (id) ON DELETE CASCADE,
CONSTRAINT wkf_witm_trans_inst_id_fkey FOREIGN KEY (inst_id) REFERENCES wkf_instance (id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE ir_module_module (
id BIGINT AUTO_INCREMENT NOT NULL,
create_uid BIGINT,
+1 -7
View File
@@ -230,7 +230,7 @@ class Database(DatabaseInterface):
if (len(line)>0) and (not line.isspace()):
cursor.execute(line)
for i in ('ir', 'workflow', 'res', 'webdav'):
for i in ('ir', 'res', 'webdav'):
root_path = os.path.join(os.path.dirname(__file__), '..', '..')
tryton_file = os.path.join(root_path, i, '__tryton__.py')
with open(tryton_file) as fp:
@@ -383,12 +383,6 @@ class Cursor(CursorInterface):
"'ir_ui_menu', "
"'res_user', "
"'res_group', "
"'wkf', "
"'wkf_activity', "
"'wkf_transition', "
"'wkf_instance', "
"'wkf_workitem', "
"'wkf_witm_trans', "
"'ir_module_module', "
"'ir_module_module_dependency', "
"'ir_translation', "
-83
View File
@@ -109,89 +109,6 @@ CREATE TABLE "res_user-res_group" (
PRIMARY KEY(id)
);
CREATE SEQUENCE wkf_id_seq;
CREATE TABLE wkf (
id INTEGER DEFAULT NEXTVAL('wkf_id_seq') NOT NULL,
name VARCHAR,
model VARCHAR,
on_create BOOL NOT NULL,
PRIMARY KEY(id)
);
CREATE SEQUENCE wkf_activity_id_seq;
CREATE TABLE wkf_activity (
id INTEGER DEFAULT NEXTVAL('wkf_activity_id_seq') NOT NULL,
workflow INTEGER,
subflow INTEGER,
split_mode VARCHAR NOT NULL,
join_mode VARCHAR NOT NULL,
name VARCHAR NOT NULL,
signal_send VARCHAR,
flow_start BOOLEAN NOT NULL,
flow_stop BOOLEAN NOT NULL,
stop_other BOOLEAN NOT NULL,
action VARCHAR,
PRIMARY KEY(id),
FOREIGN KEY (workflow) REFERENCES wkf (id) ON DELETE CASCADE,
FOREIGN KEY (subflow) REFERENCES wkf (id) ON DELETE SET NULL
);
CREATE SEQUENCE wkf_transition_id_seq;
CREATE TABLE wkf_transition (
id INTEGER DEFAULT NEXTVAL('wkf_transition_id_seq') NOT NULL,
act_from INTEGER NOT NULL,
act_to INTEGER NOT NULL,
condition VARCHAR NOT NULL,
trigger_expr_id VARCHAR,
signal VARCHAR,
"group" INTEGER,
PRIMARY KEY(id),
FOREIGN KEY (act_from) REFERENCES wkf_activity (id) ON DELETE CASCADE,
FOREIGN KEY (act_to) REFERENCES wkf_activity (id) ON DELETE CASCADE,
FOREIGN KEY ("group") REFERENCES res_group (id) ON DELETE SET NULL
);
CREATE SEQUENCE wkf_instance_id_seq;
CREATE TABLE wkf_instance (
id INTEGER DEFAULT NEXTVAL('wkf_instance_id_seq') NOT NULL,
workflow INTEGER,
uid INTEGER DEFAULT 0,
res_id INT NOT NULL DEFAULT 0,
res_type VARCHAR NOT NULL,
state VARCHAR NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY (workflow) REFERENCES wkf (id) ON DELETE RESTRICT
);
CREATE SEQUENCE wkf_workitem_id_seq;
CREATE TABLE wkf_workitem (
id INTEGER DEFAULT NEXTVAL('wkf_workitem_id_seq') NOT NULL,
activity INTEGER NOT NULL,
instance INTEGER NOT NULL,
subflow INTEGER,
state VARCHAR,
PRIMARY KEY(id),
FOREIGN KEY (activity) REFERENCES wkf_activity (id) ON DELETE CASCADE,
FOREIGN KEY (instance) REFERENCES wkf_instance (id) ON DELETE CASCADE,
FOREIGN KEY (subflow) REFERENCES wkf_instance (id) ON DELETE CASCADE
);
CREATE SEQUENCE wkf_witm_trans_id_seq;
CREATE TABLE wkf_witm_trans (
id INTEGER DEFAULT NEXTVAL('wkf_witm_trans_id_seq') NOT NULL,
trans_id INTEGER NOT NULL,
inst_id INTEGER NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY (trans_id) REFERENCES wkf_transition ON DELETE CASCADE,
FOREIGN KEY (inst_id) REFERENCES wkf_instance ON DELETE CASCADE
);
CREATE SEQUENCE ir_module_module_id_seq;
CREATE TABLE ir_module_module (
+1 -7
View File
@@ -218,7 +218,7 @@ class Database(DatabaseInterface):
if (len(line)>0) and (not line.isspace()):
cursor.execute(line)
for i in ('ir', 'workflow', 'res', 'webdav'):
for i in ('ir', 'res', 'webdav'):
root_path = os.path.join(os.path.dirname(__file__), '..', '..')
tryton_file = os.path.join(root_path, i, '__tryton__.py')
with open(tryton_file) as fp:
@@ -323,12 +323,6 @@ class Cursor(CursorInterface):
"'ir_ui_menu', "
"'res_user', "
"'res_group', "
"'wkf', "
"'wkf_activity', "
"'wkf_transition', "
"'wkf_instance', "
"'wkf_workitem', "
"'wkf_witm_trans', "
"'ir_module_module', "
"'ir_module_module_dependency', "
"'ir_translation', "
-54
View File
@@ -77,60 +77,6 @@ CREATE TABLE "res_user-res_group" (
"group" INTEGER
);
CREATE TABLE wkf (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR,
model VARCHAR,
on_create BOOLEAN
);
CREATE TABLE wkf_activity (
id INTEGER PRIMARY KEY AUTOINCREMENT,
workflow INTEGER,
subflow INTEGER,
split_mode VARCHAR,
join_mode VARCHAR,
name VARCHAR,
signal_send VARCHAR,
flow_start BOOLEAN,
flow_stop BOOLEAN,
stop_other BOOLEAN,
action VARCHAR
);
CREATE TABLE wkf_transition (
id INTEGER PRIMARY KEY AUTOINCREMENT,
act_from INTEGER,
act_to INTEGER,
condition VARCHAR,
trigger_expr_id VARCHAR,
signal VARCHAR,
"group" INTEGER
);
CREATE TABLE wkf_instance (
id INTEGER PRIMARY KEY AUTOINCREMENT,
workflow INTEGER,
uid INTEGER DEFAULT 0,
res_id INTEGER DEFAULT 0,
res_type VARCHAR,
state VARCHAR
);
CREATE TABLE wkf_workitem (
id INTEGER PRIMARY KEY AUTOINCREMENT,
activity INTEGER,
instance INTEGER,
subflow INTEGER,
state VARCHAR
);
CREATE TABLE wkf_witm_trans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
trans_id INTEGER,
inst_id INTEGER
);
CREATE TABLE ir_module_module (
id INTEGER PRIMARY KEY AUTOINCREMENT,
create_uid INTEGER,
-57
View File
@@ -794,7 +794,6 @@ def post_import(pool, module, to_delete):
cursor = Transaction().cursor
mdata_delete = []
modeldata_obj = pool.get("ir.model.data")
transition_delete = []
with Transaction().set_context(active_test=False):
mdata_ids = modeldata_obj.search([
@@ -806,48 +805,6 @@ def post_import(pool, module, to_delete):
for mrec in modeldata_obj.browse(mdata_ids):
mdata_id, model, db_id = mrec.id, mrec.model, mrec.db_id
# Whe skip transitions, they will be deleted with the
# corresponding activity:
if model == 'workflow.transition':
transition_delete.append((mdata_id, db_id))
continue
if model == 'workflow.activity':
wkf_todo = []
# search for records that are in the state/activity that
# we want to delete...
cursor.execute('SELECT res_type, res_id ' \
'FROM wkf_instance ' \
'WHERE id IN (' \
'SELECT instance FROM wkf_workitem ' \
'WHERE activity = %s)', (db_id,))
#... connect the transitions backward...
wkf_todo.extend(cursor.fetchall())
cursor.execute("UPDATE wkf_transition " \
'SET condition = \'True\', "group" = NULL, ' \
"signal = NULL, act_to = act_from, " \
"act_from = %s " \
"WHERE act_to = %s", (db_id, db_id))
# ... and force the record to follow them:
for wkf_model, wkf_model_id in wkf_todo:
model_obj = pool.get(wkf_model)
#XXX must perhaps use workflow_trigger_trigger?
model_obj.workflow_trigger_write(wkf_model_id)
# Collect the ids of these transition in model_data
cursor.execute(
"SELECT md.id FROM ir_model_data md " \
"JOIN wkf_transition t ON "\
"(md.model='workflow.transition' and md.db_id=t.id)" \
"WHERE t.act_to = %s", (db_id,))
mdata_delete.extend([x[0] for x in cursor.fetchall()])
# And finally delete the transitions
cursor.execute("DELETE FROM wkf_transition " \
"WHERE act_to = %s", (db_id,))
logging.getLogger("convert").info(
'Deleting %s@%s' % (db_id, model))
try:
@@ -873,20 +830,6 @@ def post_import(pool, module, to_delete):
'Exception: %s' %
(db_id, model, tb_s))
transition_obj = pool.get('workflow.transition')
for mdata_id, db_id in transition_delete:
logging.getLogger("convert").info(
'Deleting %s@workflow.transition' % (db_id,))
try:
transition_obj.delete(db_id)
mdata_delete.append(mdata_id)
cursor.commit()
except Exception:
cursor.rollback()
logging.getLogger("convert").error(
'Could not delete id: %d of model workflow.transition' %
(db_id,))
# Clean model_data:
if mdata_delete:
modeldata_obj.delete(mdata_delete)
+54
View File
@@ -481,6 +481,60 @@ class ModelFieldAccess(ModelSQL, ModelView):
ModelFieldAccess()
class ModelButton(ModelSQL, ModelView):
"Model Button"
_name = 'ir.model.button'
_description = __doc__
name = fields.Char('Name', required=True, readonly=True)
model = fields.Many2One('ir.model', 'Model', required=True, readonly=True,
ondelete='CASCADE', select=True)
groups = fields.Many2Many('ir.model.button-res.group', 'button', 'group',
'Groups')
def __init__(self):
super(ModelButton, self).__init__()
self._sql_constraints += [
('name_model_uniq', 'UNIQUE(name, model)',
'The button name in model must be unique!'),
]
self._order.insert(0, ('model', 'ASC'))
def create(self, values):
result = super(ModelButton, self).create(values)
# Restart the cache for get_groups
self.get_groups.reset()
return result
def write(self, ids, values):
result = super(ModelButton, self).write(ids, values)
# Restart the cache for get_groups
self.get_groups.reset()
return result
def delete(self, ids):
result = super(ModelButton, self).delete(ids)
# Restart the cache for get_groups
self.get_groups.reset()
return result
@Cache('ir.model.button')
def get_groups(self, model, name):
'''
Return a set of group ids for the named button on the model.
'''
button_ids = self.search([
('model', '=', model),
('name', '=', name),
])
if not button_ids:
return set()
button_id, = button_ids
button = self.browse(button_id)
return set(g.id for g in button.groups)
ModelButton()
class ModelData(ModelSQL, ModelView):
"Model data"
_name = 'ir.model.data'
+47
View File
@@ -261,5 +261,52 @@ this repository contains the full copyright notices and license terms. -->
<field name="action" ref="print_model_graph"/>
</record>
<record model="ir.ui.view" id="model_button_view_list">
<field name="model">ir.model.button</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Buttons">
<field name="model"/>
<field name="name"/>
</tree>
]]>
</field>
</record>
<record model="ir.ui.view" id="model_button_view_form">
<field name="model">ir.model.button</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Button">
<label name="model"/>
<field name="model"/>
<label name="name"/>
<field name="name"/>
<field name="groups" colspan="4"/>
</form>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_model_button_form">
<field name="name">Buttons</field>
<field name="res_model">ir.model.button</field>
</record>
<record model="ir.action.act_window.view"
id="act_model_button_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="model_button_view_list"/>
<field name="act_window" ref="act_model_button_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_model_button_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="model_button_view_form"/>
<field name="act_window" ref="act_model_button_form"/>
</record>
<menuitem parent="menu_model_access_form"
action="act_model_button_form" id="menu_model_button_form"/>
</data>
</tryton>
+34 -13
View File
@@ -9,6 +9,7 @@ from trytond.wizard import Wizard, StateView, Button, StateTransition, \
from trytond.backend import Database, TableHandler
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.pyson import Eval
class Module(ModelSQL, ModelView):
@@ -43,12 +44,6 @@ class Module(ModelSQL, ModelView):
]
self._order.insert(0, ('name', 'ASC'))
self._rpc.update({
'button_install': True,
'button_install_cancel': True,
'button_uninstall': True,
'button_uninstall_cancel': True,
'button_upgrade': True,
'button_upgrade_cancel': True,
'on_write': False,
})
self._error_messages.update({
@@ -58,6 +53,26 @@ class Module(ModelSQL, ModelView):
'uninstall_dep': 'The modules you are trying to uninstall ' \
'depends on installed modules:',
})
self._buttons.update({
'install': {
'invisible': Eval('state') != 'uninstalled',
},
'install_cancel': {
'invisible': Eval('state') != 'to_install',
},
'uninstall': {
'invisible': Eval('state') != 'installed',
},
'uninstall_cancel': {
'invisible': Eval('state') != 'to_remove',
},
'upgrade': {
'invisible': Eval('state') != 'installed',
},
'upgrade_cancel': {
'invisible': Eval('state') != 'to upgrade',
},
})
def default_state(self):
return 'uninstalled'
@@ -66,7 +81,7 @@ class Module(ModelSQL, ModelView):
def get_module_info(name):
"Return the content of the __tryton__.py"
try:
if name in ['ir', 'workflow', 'res', 'webdav']:
if name in ['ir', 'res', 'webdav']:
file_p = tools.file_open(os.path.join(name, '__tryton__.py'))
else:
file_p = tools.file_open(os.path.join(name, '__tryton__.py'))
@@ -198,16 +213,19 @@ class Module(ModelSQL, ModelView):
'state': 'to upgrade',
})
def button_install(self, ids):
@ModelView.button
def install(self, ids):
return self.state_install(ids)
def button_install_cancel(self, ids):
@ModelView.button
def install_cancel(self, ids):
self.write(ids, {
'state': 'uninstalled',
})
return True
def button_uninstall(self, ids):
@ModelView.button
def uninstall(self, ids):
cursor = Transaction().cursor
for module in self.browse(ids):
cursor.execute('SELECT m.state, m.name ' \
@@ -225,14 +243,17 @@ class Module(ModelSQL, ModelView):
self.write(ids, {'state': 'to remove'})
return True
def button_uninstall_cancel(self, ids):
@ModelView.button
def uninstall_cancel(self, ids):
self.write(ids, {'state': 'installed'})
return True
def button_upgrade(self, ids):
@ModelView.button
def upgrade(self, ids):
return self.state_upgrade(ids)
def button_upgrade_cancel(self, ids):
@ModelView.button
def upgrade_cancel(self, ids):
self.write(ids, {'state': 'installed'})
return True
+13 -13
View File
@@ -32,17 +32,17 @@ this repository contains the full copyright notices and license terms. -->
<label name="state"/>
<field name="state" readonly="1"/>
<group col="2" colspan="2" id="button">
<button string="Mark for Upgrade" name="button_upgrade"
<button string="Mark for Upgrade" name="upgrade"
type="object"/>
<button string="Mark for Uninstallation (beta)" name="button_uninstall"
<button string="Mark for Uninstallation (beta)" name="uninstall"
type="object"/>
<button string="Mark for Installation" name="button_install"
<button string="Mark for Installation" name="install"
type="object"/>
<button string="Cancel Installation" name="button_install_cancel"
<button string="Cancel Installation" name="install_cancel"
type="object"/>
<button string="Cancel Upgrade" name="button_upgrade_cancel"
<button string="Cancel Upgrade" name="upgrade_cancel"
type="object"/>
<button string="Cancel Uninstallation" name="button_uninstall_cancel"
<button string="Cancel Uninstallation" name="uninstall_cancel"
type="object"/>
</group>
</form>
@@ -63,14 +63,14 @@ this repository contains the full copyright notices and license terms. -->
<field name="website"/>
<field name="state"/>
<field name="description" tree_invisible="1"/>
<button string="Mark for Upgrade" name="button_upgrade"
<button string="Mark for Upgrade" name="upgrade"
type="object"/>
<button string="Mark for Installation" name="install"
type="object"/>
<button string="Cancel Installation" name="install_cancel"
type="object"/>
<button string="Cancel Upgrade" name="upgrade_cancel"
type="object"/>
<button string="Mark for Installation"
name="button_install" type="object"/>
<button string="Cancel Installation"
name="button_install_cancel" type="object"/>
<button string="Cancel Upgrade"
name="button_upgrade_cancel" type="object"/>
</tree>
]]>
</field>
-1
View File
@@ -908,7 +908,6 @@ class TranslationClean(Wizard):
'too_many_relations_found',
'xml_id_syntax_error',
'reference_syntax_error',
'delete_workflow_record',
'domain_validation_record',
'required_validation_record',
'size_validation_record',
-9
View File
@@ -141,15 +141,6 @@ this repository contains the full copyright notices and license terms. -->
<field name="module">ir</field>
<field name="fuzzy" eval="False"/>
</record>
<record model="ir.translation" id="translation_delete_workflow_record">
<field name="name">delete_workflow_record</field>
<field name="lang">en_US</field>
<field name="type">error</field>
<field name="src">You cannot delete a record with a running workflow.</field>
<field name="value">You cannot delete a record with a running workflow.</field>
<field name="module">ir</field>
<field name="fuzzy" eval="False"/>
</record>
<record model="ir.translation" id="translation_domain_validation_record">
<field name="name">domain_validation_record</field>
<field name="lang">en_US</field>
+2 -2
View File
@@ -138,8 +138,8 @@ attlist.button &=
[ a:defaultValue = "Unknown" ] attribute string { text }?
attlist.button &= attribute icon { text }?
attlist.button &=
[ a:defaultValue = "workflow" ]
attribute type { "workflow" | "object" | "action" }?
[ a:defaultValue = "object" ]
attribute type { "object" | "action" }?
attlist.button &= attribute confirm { text }?
attlist.button &= attribute name { text }
attlist.button &= attribute states { text }?
+1 -2
View File
@@ -532,9 +532,8 @@
</define>
<define name="attlist.button" combine="interleave">
<optional>
<attribute name="type" a:defaultValue="workflow">
<attribute name="type" a:defaultValue="object">
<choice>
<value>workflow</value>
<value>object</value>
<value>action</value>
</choice>
+2 -2
View File
@@ -55,8 +55,8 @@ attlist.button &= attribute help { text }?
attlist.button &=
[ a:defaultValue = "Unknown" ] attribute string { text }?
attlist.button &=
[ a:defaultValue = "workflow" ]
attribute type { "workflow" | "object" | "action" }?
[ a:defaultValue = "object" ]
attribute type { "object" | "action" }?
attlist.button &= attribute confirm { text }?
attlist.button &= attribute name { text }
attlist.button &= attribute states { text }?
+1 -2
View File
@@ -165,9 +165,8 @@
</define>
<define name="attlist.button" combine="interleave">
<optional>
<attribute name="type" a:defaultValue="workflow">
<attribute name="type" a:defaultValue="object">
<choice>
<value>workflow</value>
<value>object</value>
<value>action</value>
</choice>
+1 -1
View File
@@ -5,4 +5,4 @@ from .modelview import *
from .modelstorage import *
from .modelsingleton import *
from .modelsql import *
from .modelworkflow import *
from .workflow import Workflow
-23
View File
@@ -1153,26 +1153,3 @@ class ModelStorage(Model):
else:
vals[field] = defaults[field]
return vals
def workflow_trigger_trigger(self, ids):
'''
Trigger a trigger event.
:param ids: a list of id or an id
'''
pool = Pool()
trigger_obj = pool.get('workflow.trigger')
instance_obj = pool.get('workflow.instance')
if isinstance(ids, (int, long)):
ids = [ids]
with Transaction().set_user(0):
trigger_ids = trigger_obj.search([
('res_id', 'in', ids),
('model', '=', self._name),
])
instances = set([trigger.instance for trigger in
trigger_obj.browse(trigger_ids)])
for instance in instances:
instance_obj.update(instance)
+38
View File
@@ -7,12 +7,15 @@ except ImportError:
hashlib = None
import md5
import copy
from functools import wraps
from trytond.model import Model
from trytond.tools import safe_eval
from trytond.pyson import PYSONEncoder, CONTEXT
from trytond.transaction import Transaction
from trytond.cache import Cache
from trytond.pool import Pool
from trytond.exceptions import UserError
def _find(tree, element):
if element.tag == 'xpath':
@@ -96,6 +99,7 @@ class ModelView(Model):
super(ModelView, self).__init__()
self._rpc['fields_view_get'] = False
self._rpc['view_toolbar_get'] = False
self._buttons = {}
@Cache('modelview.fields_view_get')
def fields_view_get(self, view_id=None, view_type='form', hexmd5=None):
@@ -386,6 +390,8 @@ class ModelView(Model):
pool = Pool()
translation_obj = pool.get('ir.translation')
model_data_obj = pool.get('ir.model.data')
button_obj = pool.get('ir.model.button')
user_obj = pool.get('res.user')
if fields_width is None:
fields_width = {}
@@ -458,6 +464,21 @@ class ModelView(Model):
element.set(attr, encoder.encode(safe_eval(element.get(attr),
CONTEXT)))
if element.tag == 'button':
if element.get('type', 'object') == 'object':
assert not element.get('states')
button_name = element.attrib['name']
if button_name in self._buttons:
states = self._buttons[button_name]
else:
states = {}
groups = set(user_obj.get_groups())
button_groups = button_obj.get_groups(self._name, button_name)
if button_groups and not groups & button_groups:
states = states.copy()
states['readonly'] = True
element.set('states', encoder.encode(states))
# translate view
if Transaction().language != 'en_US' and not result:
for attr in ('string', 'sum', 'confirm', 'help'):
@@ -480,3 +501,20 @@ class ModelView(Model):
fields_attrs.update(self.__view_look_dom(field, type,
fields_width=fields_width))
return fields_attrs
@staticmethod
def button(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
pool = Pool()
button_obj = pool.get('ir.model.button')
user_obj = pool.get('res.user')
if Transaction().user != 0:
groups = set(user_obj.get_groups())
button_groups = button_obj.get_groups(self._name, func.__name__)
if button_groups and not groups & button_groups:
raise UserError('Calling button %s on %s is not allowed!'
% (func.__name__, self._name))
return func(self, *args, **kwargs)
return wrapper
-133
View File
@@ -1,133 +0,0 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.model import ModelStorage
from trytond.transaction import Transaction
from trytond.pool import Pool
class ModelWorkflow(ModelStorage):
'''
Define a model with a workflow in Tryton.
'''
def __init__(self):
super(ModelWorkflow, self).__init__()
self._rpc.update({
'workflow_trigger_validate': True,
})
def create(self, values):
res = super(ModelWorkflow, self).create(values)
self.workflow_trigger_create(res)
return res
def write(self, ids, values):
res = super(ModelWorkflow, self).write(ids, values)
self.workflow_trigger_write(ids)
return res
def delete(self, ids):
instance_obj = Pool().get('workflow.instance')
if isinstance(ids, (int, long)):
ids = [ids]
with Transaction().set_user(0):
if instance_obj.search([
('res_id', 'in', ids),
('res_type', '=', self._name),
('state', '!=', 'complete'),
]):
self.raise_user_error('delete_workflow_record')
res = super(ModelWorkflow, self).delete(ids)
self.workflow_trigger_delete(ids)
return res
def workflow_trigger_create(self, ids):
'''
Trigger create event
:param ids: a list of id or an id
'''
pool = Pool()
workflow_obj = pool.get('workflow')
instance_obj = pool.get('workflow.instance')
if isinstance(ids, (int, long)):
ids = [ids]
with Transaction().set_user(0):
workflow_ids = workflow_obj.search([
('model', '=', self._name),
('on_create', '=', True),
])
for res_id in ids:
for wkf_id in workflow_ids:
instance_obj.create({
'res_type': self._name,
'res_id': res_id,
'workflow': wkf_id,
'state': 'active',
})
def workflow_trigger_write(self, ids):
'''
Trigger write event
:param ids: a list of id or an id
'''
instance_obj = Pool().get('workflow.instance')
if isinstance(ids, (int, long)):
ids = [ids]
with Transaction().set_user(0):
instance_ids = instance_obj.search([
('res_id', 'in', ids),
('res_type', '=', self._name),
('state', '=', 'active'),
])
instances = instance_obj.browse(instance_ids)
for instance in instances:
instance_obj.update(instance)
def workflow_trigger_validate(self, ids, signal):
'''
Trigger validate event
:param ids: a list of id or an id
'''
instance_obj = Pool().get('workflow.instance')
if isinstance(ids, (int, long)):
ids = [ids]
with Transaction().set_user(0):
instance_ids = instance_obj.search([
('res_id', 'in', ids),
('res_type', '=', self._name),
('state', '=', 'active'),
])
instances = instance_obj.browse(instance_ids)
for instance in instances:
instance_obj.validate(instance, signal=signal)
def workflow_trigger_delete(self, ids):
'''
Trigger delete event
:param ids: a list of id or an id
'''
if self._name == 'workflow.instance':
return
instance_obj = Pool().get('workflow.instance')
if isinstance(ids, (int, long)):
ids = [ids]
with Transaction().set_user(0):
instance_ids = instance_obj.search([
('res_id', 'in', ids),
('res_type', '=', self._name),
])
instance_obj.delete(instance_ids)
+40
View File
@@ -0,0 +1,40 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from functools import wraps
class Workflow(object):
"""
Mix-in class to handle transition check.
"""
_transition_state = 'state'
def __init__(self):
super(Workflow, self).__init__()
self._transitions = set()
@staticmethod
def transition(state):
def check_transition(func):
@wraps(func)
def wrapper(self, ids, *args, **kwargs):
records = self.browse(ids)
filtered = []
to_update = []
for record in records:
current_state = getattr(record, self._transition_state)
transition = (current_state, state)
if transition in self._transitions:
filtered.append(record.id)
if current_state != state:
to_update.append(record.id)
result = func(self, filtered, *args, **kwargs)
if to_update:
self.write(to_update, {
self._transition_state: state,
})
return result
return wrapper
return check_transition
+5 -4
View File
@@ -132,7 +132,7 @@ def create_graph(module_list):
for module in module_list:
tryton_file = OPJ(MODULES_PATH, module, '__tryton__.py')
mod_path = OPJ(MODULES_PATH, module)
if module in ('ir', 'workflow', 'res', 'webdav', 'test'):
if module in ('ir', 'res', 'webdav', 'test'):
root_path = os.path.abspath(os.path.dirname(
os.path.dirname(__file__)))
tryton_file = OPJ(root_path, module, '__tryton__.py')
@@ -294,7 +294,6 @@ def get_module_list():
update_egg_modules()
module_list.update(EGG_MODULES.keys())
module_list.add('ir')
module_list.add('workflow')
module_list.add('res')
module_list.add('webdav')
module_list.add('test')
@@ -305,7 +304,6 @@ def register_classes():
Import modules to register the classes in the Pool
'''
import trytond.ir
import trytond.workflow
import trytond.res
import trytond.webdav
import trytond.test
@@ -315,7 +313,7 @@ def register_classes():
module = package.name
logger.info('%s:registering classes' % module)
if module in ('ir', 'workflow', 'res', 'webdav', 'test'):
if module in ('ir', 'res', 'webdav', 'test'):
MODULES.append(module)
continue
@@ -366,6 +364,9 @@ def load_modules(database_name, pool, update=False, lang=None):
with contextmanager:
cursor = Transaction().cursor
if update:
# Migration from 2.2: workflow module removed
cursor.execute('DELETE FROM ir_module_module '
'WHERE name = %s', ('workflow',))
if 'all' in CONFIG['init']:
cursor.execute("SELECT name FROM ir_module_module " \
"WHERE name != \'test\'")
+5 -2
View File
@@ -129,11 +129,14 @@ def dispatch(host, port, protocol, database_name, user, session, object_type,
pool.init()
obj = pool.get(object_name, type=object_type)
if method not in obj._rpc:
if method in obj._rpc:
readonly = not obj._rpc[method]
elif method in getattr(obj, '_buttons', {}):
readonly = False
else:
raise UserError('Calling method %s on %s %s is not allowed!'
% (method, object_type, object_name))
readonly = not obj._rpc[method]
for count in range(int(CONFIG['retry']), -1, -1):
with Transaction().start(database_name, user,
+42
View File
@@ -118,6 +118,48 @@ class ModelFieldGroup(ModelSQL):
ModelFieldGroup()
class ModelButtonGroup(ModelSQL):
"Model Button - Group"
_name = 'ir.model.button-res.group'
_description = __doc__
button = fields.Many2One('ir.model.button', 'Button',
ondelete='CASCADE', select=True, required=True)
group = fields.Many2One('res.group', 'Group', ondelete='CASCADE',
select=True, required=True)
active = fields.Boolean('Active', select=True)
def __init__(self):
super(ModelButtonGroup, self).__init__()
for method in self._rpc:
self._rpc[method] = False
def default_active(self):
return True
def create(self, values):
pool = Pool()
result = super(ModelButtonGroup, self).create(values)
# Restart the cache for get_groups
pool.get('ir.model.button').get_groups.reset()
return result
def write(self, ids, values):
pool = Pool()
result = super(ModelButtonGroup, self).write(ids, values)
# Restart the cache for get_groups
pool.get('ir.model.button').get_groups.reset()
return result
def delete(self, ids):
pool = Pool()
result = super(ModelButtonGroup, self).delete(ids)
# Restart the cache for get_groups
pool.get('ir.model.button').get_groups.reset()
return result
ModelButtonGroup()
class RuleGroupGroup(ModelSQL):
"Rule Group - Group"
_name = 'ir.rule.group-res.group'
+73 -88
View File
@@ -228,6 +228,21 @@ this repository contains the full copyright notices and license terms. -->
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.access" id="access_ir_model_button">
<field name="model" search="[('model', '=', 'ir.model.button')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_ir_model_button_admin">
<field name="model" search="[('model', '=', 'ir.model.button')]"/>
<field name="group" ref="group_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.access" id="access_ir_model_data">
<field name="model" search="[('model', '=', 'ir.model.data')]"/>
<field name="perm_read" eval="True"/>
@@ -602,95 +617,65 @@ this repository contains the full copyright notices and license terms. -->
<field name="menu" ref="ir.menu_trigger_form"/>
<field name="group" ref="group_admin"/>
</record>
<record model="ir.ui.view" id="module_view_form">
<field name="model">ir.module.module</field>
<field name="inherit" ref="ir.module_view_form"/>
<field name="arch" type="xml">
<![CDATA[
<data>
<xpath
expr="/form/group/button[@name=&quot;button_install&quot;]"
position="replace">
<button string="Mark for Installation" name="button_install"
type="object"
states="{'invisible': Not(Equal(Eval('state'), 'uninstalled')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/form/group/button[@name=&quot;button_install_cancel&quot;]"
position="replace">
<button string="Cancel Installation" name="button_install_cancel"
type="object"
states="{'invisible': Not(Equal(Eval('state'), 'to install')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/form/group/button[@name=&quot;button_uninstall&quot;]"
position="replace">
<button string="Mark for Uninstallation (beta)" name="button_uninstall"
type="object"
states="{'invisible': Not(Equal(Eval('state'), 'installed')), 'readonly': Bool(True)}"/>
</xpath>
<xpath
expr="/form/group/button[@name=&quot;button_uninstall_cancel&quot;]"
position="replace">
<button string="Cancel Uninstallation" name="button_uninstall_cancel"
type="object"
states="{'invisible': Not(Equal(Eval('state'), 'to remove')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/form/group/button[@name=&quot;button_upgrade&quot;]"
position="replace">
<button string="Mark for Upgrade" name="button_upgrade"
type="object"
states="{'invisible': Not(Equal(Eval('state'), 'installed')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/form/group/button[@name=&quot;button_upgrade_cancel&quot;]"
position="replace">
<button string="Cancel Upgrade" name="button_upgrade_cancel"
type="object"
states="{'invisible': Not(Equal(Eval('state'), 'to upgrade')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
</data>
]]>
</field>
<record model="ir.model.button" id="module_install_button">
<field name="name">install</field>
<field name="model" search="[('model', '=', 'ir.module.module')]"/>
</record>
<record model="ir.ui.view" id="module_view_tree">
<field name="model">ir.module.module</field>
<field name="inherit" ref="ir.module_view_tree"/>
<field name="arch" type="xml">
<![CDATA[
<data>
<xpath
expr="/tree/button[@name=&quot;button_install&quot;]"
position="replace">
<button string="Mark for Installation"
name="button_install" type="object"
states="{'invisible': Not(Equal(Eval('state'), 'uninstalled')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/tree/button[@name=&quot;button_install_cancel&quot;]"
position="replace">
<button string="Cancel Installation"
name="button_install_cancel" type="object"
states="{'invisible': Not(Equal(Eval('state'), 'to install')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/tree/button[@name=&quot;button_upgrade&quot;]"
position="replace">
<button string="Mark for Upgrade"
name="button_upgrade" type="object"
states="{'invisible': Not(Equal(Eval('state'), 'installed')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
<xpath
expr="/tree/button[@name=&quot;button_upgrade_cancel&quot;]"
position="replace">
<button string="Cancel Upgrade"
name="button_upgrade_cancel" type="object"
states="{'invisible': Not(Equal(Eval('state'), 'to upgrade')), 'readonly': Not(In(%(res.group_admin)d, Eval('groups', [])))}"/>
</xpath>
</data>
]]>
</field>
<record model="ir.model.button-res.group"
id="module_install_button_group_admin">
<field name="button" ref="module_install_button"/>
<field name="group" ref="group_admin"/>
</record>
<record model="ir.model.button" id="module_install_cancel_button">
<field name="name">install_cancel</field>
<field name="model" search="[('model', '=', 'ir.module.module')]"/>
</record>
<record model="ir.model.button-res.group"
id="module_install_cancel_button_group_admin">
<field name="button" ref="module_install_cancel_button"/>
<field name="group" ref="group_admin"/>
</record>
<record model="ir.model.button" id="module_uninstall_button">
<field name="name">uninstall</field>
<field name="model" search="[('model', '=', 'ir.module.module')]"/>
</record>
<record model="ir.model.button-res.group"
id="module_uninstall_button_group_admin">
<field name="button" ref="module_uninstall_button"/>
<field name="group" ref="group_admin"/>
</record>
<record model="ir.model.button" id="module_uninstall_cancel_button">
<field name="name">uninstall_cancel</field>
<field name="model" search="[('model', '=', 'ir.module.module')]"/>
</record>
<record model="ir.model.button-res.group"
id="module_uninstall_cancel_button_group_admin">
<field name="button" ref="module_uninstall_cancel_button"/>
<field name="group" ref="group_admin"/>
</record>
<record model="ir.model.button" id="module_upgrade_button">
<field name="name">upgrade</field>
<field name="model" search="[('model', '=', 'ir.module.module')]"/>
</record>
<record model="ir.model.button-res.group"
id="module_upgrade_button_group_admin">
<field name="button" ref="module_upgrade_button"/>
<field name="group" ref="group_admin"/>
</record>
<record model="ir.model.button" id="module_upgrade_cancel_button">
<field name="name">upgrade_cancel</field>
<field name="model" search="[('model', '=', 'ir.module.module')]"/>
</record>
<record model="ir.model.button-res.group"
id="module_upgrade_cancel_button_group_admin">
<field name="button" ref="module_upgrade_cancel_button"/>
<field name="group" ref="group_admin"/>
</record>
<record model="res.request.link" id="request_link_cron">
+28 -18
View File
@@ -62,6 +62,28 @@ class Request(ModelSQL, ModelView):
state = fields.Selection(_STATES, 'State', required=True, readonly=True)
history = fields.One2Many('res.request.history', 'request',
'History', readonly=True)
def __init__(self):
super(Request, self).__init__()
self._rpc.update({
'request_get': False,
})
self._order.insert(0, ('priority', 'DESC'))
self._order.insert(1, ('trigger_date', 'DESC'))
self._order.insert(2, ('create_date', 'DESC'))
self._buttons.update({
'send': {
'invisible': ~Eval('state').in_(['draft', 'chatting']),
'readonly': Eval('act_from') != Eval('_user'),
},
'reply': {
'invisible': Eval('state') != 'waiting',
'readonly': Eval('act_to') != Eval('_user'),
},
'close': {
'invisible': ~Eval('state').in_(['waiting', 'draft',
'chatting']),
},
})
def default_act_from(self):
return int(Transaction().user)
@@ -75,18 +97,6 @@ class Request(ModelSQL, ModelView):
def default_priority(self):
return '1'
def __init__(self):
super(Request, self).__init__()
self._rpc.update({
'request_send': True,
'request_reply': True,
'request_close': True,
'request_get': False,
})
self._order.insert(0, ('priority', 'DESC'))
self._order.insert(1, ('trigger_date', 'DESC'))
self._order.insert(2, ('create_date', 'DESC'))
def on_change_with_number_references(self, vals):
if vals.get('references'):
return len(vals['references'])
@@ -101,7 +111,8 @@ class Request(ModelSQL, ModelView):
res[request.id] = 0
return res
def request_send(self, ids):
@ModelView.button
def send(self, ids):
pool = Pool()
request_history_obj = pool.get('res.request.history')
for request in self.browse(ids):
@@ -124,9 +135,9 @@ class Request(ModelSQL, ModelView):
'state': 'waiting',
'date_send': datetime.datetime.now(),
})
return True
def request_reply(self, ids):
@ModelView.button
def reply(self, ids):
user = Transaction().user
for request in self.browse(ids):
self.write(request.id, {
@@ -136,11 +147,10 @@ class Request(ModelSQL, ModelView):
'trigger_date': False,
'body': '',
})
return True
def request_close(self, ids):
@ModelView.button
def close(self, ids):
self.write(ids, {'state': 'closed', 'active': False})
return True
def request_get(self):
user = Transaction().user
+6 -9
View File
@@ -51,19 +51,16 @@ this repository contains the full copyright notices and license terms. -->
<label name="trigger_date"/>
<field name="trigger_date"/>
<group col="2" colspan="2" id="buttons">
<button name="request_send"
states="{'invisible': Not(In(Eval('state'), ['draft', 'chatting'])), 'readonly': Not(Equal(Eval('act_from'), Eval('_user')))}"
string="Send" type="object"/>
<button name="request_reply"
states="{'invisible': Not(Equal(Eval('state'), 'waiting')), 'readonly': Not(Equal(Eval('act_to'), Eval('_user')))}"
string="Reply" type="object"/>
<button name="send" string="Send"
type="object"/>
<button name="reply" string="Reply"
type="object"/>
</group>
<label name="state"/>
<field name="state"/>
<group col="3" colspan="2" id="button">
<button name="request_close"
states="{'invisible': Not(In(Eval('state'), ['waiting', 'draft', 'chatting']))}"
string="Close" type="object"/>
<button name="close" string="Close"
type="object"/>
</group>
</page>
<page string="References" col="1" id="references">
+1 -1
View File
@@ -5,7 +5,7 @@
'description': '''A module for unittest.
''',
'active': True,
'depends': ['ir', 'res', 'workflow'],
'depends': ['ir', 'res'],
'xml': [
'import_data.xml',
'sequence.xml',
+17 -23
View File
@@ -1,35 +1,29 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of this
# repository contains the full copyright notices and license terms.
from trytond.model import ModelSQL, ModelWorkflow, fields
from trytond.model import ModelSQL, Workflow, fields
class WorkflowedModel(ModelWorkflow, ModelSQL):
class WorkflowedModel(Workflow, ModelSQL):
_name = 'test.workflowed'
name = fields.Char('Name')
state = fields.Char('State')
value = fields.Integer('Value')
state = fields.Selection([
('start', 'Start'),
('running', 'Running'),
('end', 'End'),
], 'State')
def default_transitions(self):
return 0
def __init__(self):
super(WorkflowedModel, self).__init__()
self._transitions |= set((
('start', 'running'),
))
def default_value(self):
return 0
def default_state(self):
return 'start'
def workflow_start(self, workflowed):
self.write([workflowed.id], {'state': 'Start'})
def workflow_middle(self, workflowed):
self.write([workflowed.id], {'state': 'Middle'})
def workflow_end(self, workflowed):
self.write([workflowed.id], {'state': 'End'})
def start_middle_ok(self, workflowed):
return workflowed.value > 4
def middle_end_ok(self, workflowed):
return workflowed.value < 8
@Workflow.transition('running')
def run(self, ids):
pass
WorkflowedModel()
-34
View File
@@ -3,39 +3,5 @@
repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="workflow" id="test_workflow">
<field name="name">Test workflow</field>
<field name="model">test.workflowed</field>
<field name="on_create" eval="True" />
</record>
<record model="workflow.activity" id="test_activity_start">
<field name="name">Start</field>
<field name="method">workflow_start</field>
<field name="workflow" ref="test_workflow" />
<field name="flow_start" eval="True" />
</record>
<record model="workflow.activity" id="test_activity_middle">
<field name="name">Middle</field>
<field name="method">workflow_middle</field>
<field name="workflow" ref="test_workflow" />
</record>
<record model="workflow.activity" id="test_activity_end">
<field name="name">End</field>
<field name="method">workflow_end</field>
<field name="workflow" ref="test_workflow" />
<field name="flow_stop" eval="True" />
</record>
<record model="workflow.transition"
id="test_transition_start_middle">
<field name="act_from" ref="test_activity_start" />
<field name="act_to" ref="test_activity_middle" />
<field name="condition">start_middle_ok</field>
</record>
<record model="workflow.transition"
id="tes_transition_middle_end">
<field name="act_from" ref="test_activity_middle" />
<field name="act_to" ref="test_activity_end" />
<field name="condition">middle_end_ok</field>
</record>
</data>
</tryton>
+1 -11
View File
@@ -69,7 +69,6 @@ class ModelViewTestCase(unittest.TestCase):
def setUp(self):
install_module('ir')
install_module('res')
install_module('workflow')
install_module('webdav')
def test0000test(self):
@@ -88,12 +87,6 @@ class ModelViewTestCase(unittest.TestCase):
'''
test_view('res')
def test0030workflow(self):
'''
Test workflow.
'''
test_view('workflow')
def test0040webdav(self):
'''
Test webdav.
@@ -109,7 +102,6 @@ class FieldDependsTestCase(unittest.TestCase):
def setUp(self):
install_module('ir')
install_module('res')
install_module('workflow')
install_module('webdav')
def test0010depends(self):
@@ -143,7 +135,7 @@ def install_module(name):
if not module_ids:
return
module_obj.button_install(module_ids)
module_obj.install(module_ids)
transaction.cursor.commit()
install_upgrade_obj = POOL.get('ir.module.module.install_upgrade',
@@ -252,8 +244,6 @@ def all_suite():
suite_.addTests(test_access.suite())
import trytond.tests.test_mixins as test_mixins
suite_.addTests(test_mixins.suite())
import trytond.tests.test_workflow as test_workflow
suite_.addTests(test_workflow.suite())
import trytond.tests.test_wizard as test_wizard
suite_.addTests(test_wizard.suite())
return suite_
+12 -40
View File
@@ -14,49 +14,21 @@ class WorkflowTestCase(unittest.TestCase):
install_module('test')
self.workflow_obj = POOL.get('test.workflowed')
def test0010object_creation(self):
'Test workflow object creation'
with Transaction().start(DB_NAME, USER,
context=CONTEXT) as transaction:
wkf_id = self.workflow_obj.create({
'name': 'value = 3',
'value': 3,
})
self.assertEqual(self.workflow_obj.read(wkf_id)['state'], 'Start')
wkf_id = self.workflow_obj.create({
'name': 'value = 10',
'value': 10,
})
self.assertEqual(self.workflow_obj.read(wkf_id)['state'], 'Middle')
wkf_id = self.workflow_obj.create({
'name': 'value = 6',
'value': 6,
})
self.assertEqual(self.workflow_obj.read(wkf_id)['state'], 'End')
transaction.cursor.rollback()
def test0020object_modification(self):
'Test workflow object modification'
# TODO add test for Workflow.transition
def test0010transition(self):
'Test transition'
with Transaction().start(DB_NAME, USER, context=CONTEXT):
wkf_id = self.workflow_obj.create({
'name': 'value = 3',
'value': 3,
})
wkf_id = self.workflow_obj.create({
'name': 'value = 10',
'value': 10,
})
wkf_id = self.workflow_obj.create({})
wkf_id, = self.workflow_obj.search([('name', '=', 'value = 3')])
self.workflow_obj.write(wkf_id, {'value': 11})
self.assertEqual(self.workflow_obj.read(wkf_id)['state'], 'Middle')
self.workflow_obj.run([wkf_id])
self.assertEqual(self.workflow_obj.read(wkf_id)['state'],
'running')
wkf_id, = self.workflow_obj.search([('name', '=', 'value = 10')])
self.workflow_obj.write(wkf_id, {'value': 6})
self.assertEqual(self.workflow_obj.read(wkf_id)['state'], 'End')
self.workflow_obj.write(wkf_id, {
'state': 'end',
})
self.workflow_obj.run([wkf_id])
self.assertEqual(self.workflow_obj.read(wkf_id)['state'], 'end')
def suite():
-1
View File
@@ -98,7 +98,6 @@ def file_open(name, mode="r", subdir='modules'):
if subdir:
if subdir == 'modules'\
and (name.startswith('ir' + os.sep) \
or name.startswith('workflow' + os.sep) \
or name.startswith('res' + os.sep) \
or name.startswith('webdav' + os.sep) \
or name.startswith('test' + os.sep)):
-3
View File
@@ -1,3 +0,0 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from .workflow import *
-41
View File
@@ -1,41 +0,0 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
{
'name': 'Workflow',
'name_bg_BG': 'Работен процес',
'name_de_DE': 'Workflow',
'name_es_ES': 'Flujo de trabajo',
'name_fr_FR': 'Workflow',
'name_nl_NL': 'Werkgang',
'name_ru_RU': 'Бизнес процессы',
'description': '''Basic module providing concept and administration of workflows.
''',
'description_bg_BG': '''Основен модул даващ идея и администрация на работни процеси.
''',
'description_de_DE': '''Basismodul für Konzept und Administration von Workflows
''',
'description_es_ES': '''Módulo básico que provee el concepto y administración de flujos de trabajo.
''',
'description_fr_FR': '''Module de base fournissant les concepts et l'administration de workflows.
''',
'description_nl_NL': '''Basismodule voor het instellen en beheren van werkgangen.
''',
'description_ru_RU': '''Базовый модуль концепция обеспечения и администрирования рабочих процессов.
''',
'active': True,
'depends': ['ir', 'res'],
'xml': [
'workflow.xml',
],
'translation': [
'locale/cs_CZ.po',
'locale/bg_BG.po',
'locale/ca_ES.po',
'locale/de_DE.po',
'locale/es_CO.po',
'locale/es_ES.po',
'locale/fr_FR.po',
'locale/nl_NL.po',
'locale/ru_RU.po',
],
}
-340
View File
@@ -1,340 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "Не е зададен екземпляр на работен процес!"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "Не е зададен работен процес!"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Дейности"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Модел на ресурс"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "При създаване"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Стартиране на процес"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Спиране на процес"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Входящи преходи"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Режим на свързаване"
#, fuzzy
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr "Метод"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Изходящи преходи"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Сигнал (subflow.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Режим на разделяне"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr ""
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Подпоток"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Работен процес"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Препълване"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "ID на ресурс"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Модел на ресурс"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Състояние"
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Преходи"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "Потребителско ID"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Работен процес"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Задачи"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Източник на действие"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Активност на местонахождение-цел"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Условие"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Групата е задължителна"
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Екземпляри"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Сигнал (име на бутон)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr ""
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Вид превключвател"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Екземпляр"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Преход"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Ексемплят на местонахождение-цел"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Модел"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "ID на ресурс"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Задача"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Дейност"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Екземпляр"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Име"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Състояние"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Подпоток"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Дейности"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Екземпляри"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Преходи"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Работни процеси"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Задачи"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Дейности"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Екземпляри"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Преходи"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Работен процес"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Работни процеси"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Задачи"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Работен процес"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Дейности"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Екземплят на работен процес"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Преход на работен процес"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Преход на работен процес - екземпляр"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Задействане на работен процес"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "Задачи от работен процес"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "и"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "Xor"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "и"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "Или"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "Xor"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Дейност"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Преход"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Преходи"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Екземпляр"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Екземпляри"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Преход"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Преходи"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Задача"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Задачи"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Работен процес"
-358
View File
@@ -1,358 +0,0 @@
#
# Albert Cervera i Areny <albert@nan-tic.com>, 2011.
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Last-Translator: Albert Cervera i Areny <albert@nan-tic.com>\n"
"PO-Revision-Date: 2011-10-22 13:52+0200\n"
"Project-Id-Version: \n"
"Language-Team: Catalan <>\n"
"Language: ca\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.2\n"
"MIME-Version: 1.0\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "No s'ha definit cap instància de flux de treball"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "No s'ha definit cap flux de treball"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Activitats"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Model del recurs"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "En ser creat"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.activity,action:0"
msgid "Action"
msgstr "Acció"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Inici del flux"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Fi del flux"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Transicions entrants"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Mode d'unió"
msgctxt "field:workflow.activity,kind:0"
msgid "Kind"
msgstr "Tipus"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Transicions de sortida"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Senyal (subflux.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Mode de divisió"
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Subflux"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Flux de treball"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Desbordament"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "ID del recurs"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Model del recurs"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Estat"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "ID de l'usuari"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Flux de treball"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Elements de treball"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Activitat origen"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Activitat de destí"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Condició"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Es requereix un grup"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Senyal (Nom del botó)"
msgctxt "field:workflow.transition,trigger_expr_id:0"
msgid "Trigger Expr ID"
msgstr "ID expr. del disparador"
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Tipus de disparador"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Instància"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Transició"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Instància de destinació"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Model"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "ID del recurs"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Element de treball"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Activitat"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Instància"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Estat"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Subflux"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Activitats"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Instàncies"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Transicions"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Fluxos de treball"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Elements de treball"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Activitats"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Instàncies"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Transicions"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Flux de treball"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Fluxos de treball"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Elements de treball"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Flux de treball"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Activitat del flux de treball"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Instància del flux de treball"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Transició del flux de treball"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Transició del flux de treball - Instància"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Disparador del flux de treball"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "element del flux de treball"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "I"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "O exclusiva"
msgctxt "selection:workflow.activity,kind:0"
msgid "Dummy"
msgstr "Objecte fictici"
msgctxt "selection:workflow.activity,kind:0"
msgid "Function"
msgstr "Funció"
msgctxt "selection:workflow.activity,kind:0"
msgid "Stop All"
msgstr "Aturar-los tots"
msgctxt "selection:workflow.activity,kind:0"
msgid "Subflow"
msgstr "Subflux"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "I"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "O"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "O exclusiva"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Activitat"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Transició"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Transicions"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Instància"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Instàncies"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Transició"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Transicions"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Element de treball"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Elements de treball"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Flux de treball"
-339
View File
@@ -1,339 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr ""
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr ""
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr ""
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr ""
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr ""
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr ""
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr ""
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr ""
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr ""
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr ""
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr ""
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr ""
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr ""
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr ""
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr ""
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr ""
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr ""
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr ""
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr ""
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr ""
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr ""
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr ""
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr ""
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr ""
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr ""
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr ""
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr ""
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr ""
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr ""
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr ""
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr ""
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr ""
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr ""
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr ""
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr ""
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr ""
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr ""
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr ""
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr ""
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr ""
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr ""
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr ""
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr ""
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr ""
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr ""
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr ""
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr ""
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr ""
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr ""
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr ""
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr ""
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr ""
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr ""
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr ""
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr ""
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr ""
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr ""
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr ""
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr ""
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr ""
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr ""
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr ""
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr ""
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr ""
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr ""
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr ""
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr ""
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr ""
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr ""
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr ""
-339
View File
@@ -1,339 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "Keine Workflowinstanz definiert!"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "Kein Workflow definiert!"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Aktivitäten"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Modell Ressource"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "Bei der Erstellung"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Flow Start"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Flow Stop"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Eingehende Übergänge"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Verbindungsmodus"
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr "Methode"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Ausgehende Übergänge"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Signal (subflow.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Geteilter Modus"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr "Andere stoppen"
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Unterflow"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Workflow"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Überlauf"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "ID Ressource"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Modell Ressource"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Status"
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Übergänge"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "Benutzer ID"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Workflow"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Elemente"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Quelle der Aktivität"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Bestimmung der Aktivität"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Bedingung"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Erforderliche Gruppe"
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Instanzen"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Signal (Name des Knopfes)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr "Trigger Ausdruck ID"
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Typ Trigger"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Instanz"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Übergang"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Bestimmungsinstanz"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Modell"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "ID Ressource"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Element"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Aktivität"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Instanz"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Name"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Status"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Unterflow"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Aktivitäten"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Instanzen"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Übergänge"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Workflows"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Elemente"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Aktivitäten"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Instanzen"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Übergänge"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Workflow"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Workflows"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Elemente"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Workflow"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Workflow Aktivität"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Workflow Instanz"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Workflow Übergang"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Workflow Übergang - Instanz"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Workflow Trigger"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "Workflow Element"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "Und"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "Oder (exklusiv)"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "Und"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "Oder"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "Oder (exklusiv)"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Aktivität"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Übergang"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Übergänge"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Instanz"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Instanzen"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Übergang"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Übergänge"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Element"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Elemente"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Workflow"
-342
View File
@@ -1,342 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "No ha definido la instancia de un flujo!"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "No ha definido un flujo de trabajo!"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Actividades"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Modelo del Recurso"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "Al Crear"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Comienzo de flujo"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Fin de flujo"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Transiciones entrantes"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Modo unión"
#, fuzzy
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr "Método"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Transiciones de Salida"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Señal (subflujo.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Modo dividido"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr ""
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Subflujo"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Desbordamiento"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "Identificador del Recurso"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Modelo del Recurso"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Estado"
#, fuzzy
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "Identificación del Usuario"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Objetos de trabajo"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Actividad Fuente"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Actividad destino"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Condición"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Se requiere grupo"
#, fuzzy
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Instancias"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Señal (Nombre del botón)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr ""
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Tipo de Activación"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Instancia"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Transición"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Instancia destino"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Modelo"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "Identificador del Recurso"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Objeto de trabajo"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Actividad"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Instancia"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Estado"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Subflujo"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Actividades"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Instancias"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Flujos de trabajo"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Objetos de trabajo"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Actividades"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Instancias"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Flujos de trabajo"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Objetos de trabajo"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Flujo de Trabajo"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Actividad de flujo de trabajo"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Instancia de Flujo de trabajo"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Transición de flujo de trabajo"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Transición de flujo de trabajo - Instancia"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Disparador de flujo de trabajo"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "elemento de flujo de trabajo"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "Y"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "Xor"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "Y"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "O"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "Xor"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Actividad"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Transición"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Instancia"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Instancias"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Transición"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Objeto de trabajo"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Objetos de trabajo"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Flujo de Trabajo"
-342
View File
@@ -1,342 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "No se ha definido ninguna instancia de flujo de trabajo"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "No se ha definido ningún flujo de trabajo"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Actividades"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Modelo del recurso"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "Al ser creado"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Inicio del flujo"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Fin del flujo"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Transiciones entrantes"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Modo unión"
#, fuzzy
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr "Método"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Transiciones de salida"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Señal (subflujo.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Modo dividido"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr ""
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Subflujo"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Desbordamiento"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "ID del recurso"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Modelo del recurso"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Estado"
#, fuzzy
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "ID del usuario"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Elementos de trabajo"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Actividad fuente"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Actividad de destino"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Condición"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Se requiere un grupo"
#, fuzzy
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Instancias"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Señal (Nombre del botón)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr ""
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Tipo de disparador"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Instancia"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Transición"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Instancia de destino"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Modelo"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "ID del recurso"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Elemento de trabajo"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Actividad"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Instancia"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Nombre"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Estado"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Subflujo"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Actividades"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Instancias"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Flujos de trabajo"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Elementos de trabajo"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Actividades"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Instancias"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Flujos de trabajo"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Elementos de trabajo"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Flujo de trabajo"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Actividad del flujo de trabajo"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Instancia del flujo de trabajo"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Transición del flujo de trabajo"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Transición del flujo de trabajo - Instancia"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Disparador del flujo de trabajo"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "elemento del flujo de trabajo"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "Y"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "O exclusiva"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "Y"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "O"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "O exclusiva"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Actividad"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Transición"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Instancia"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Instancias"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Transición"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Transiciones"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Elemento de trabajo"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Elementos de trabajo"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Flujo de trabajo"
-339
View File
@@ -1,339 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "Aucune instance de workflow de définie !"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "Aucun workflow de défini !"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Activités"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Modèle de la ressource"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "À la création"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Départ du flux"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Arrêt du flux"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Transitions d'entrées"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Mode de jonction"
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr "Méthode"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Transitions de sortie"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Signal (subflow.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Mode de division"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr "Arrête les autres"
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Sous-flux"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Workflow"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Overflow"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "Identifiant de la ressource"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Modèle de la ressource"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "État"
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Transitions"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "Identifiant de l'utilisateur"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Workflow"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Éléments"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Source de l'activité"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Destination de l'activité"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Condition"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Groupe requis"
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Instances"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Signal (nom du bouton)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr "Expression des ID de déclenchements"
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Type de déclenchement"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Instance"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Transition"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Destination de l'instance"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Modèle"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "Identifiant de la ressource"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Élément"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Activité"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Instance"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Nom"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "État"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Sous-flux"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Activités"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Instances"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Transitions"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Workflows"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Éléments"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Activités"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Instances"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Transitions"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Workflow"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Workflows"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Éléments"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Workflow"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Activité de workflow"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Instance de workflow"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Transition de workflow"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Transition de workflow - Instance"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Déclenchement de workflow"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "Workitem de workflow"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "Et"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "Ou exclusif"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "Et"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "Ou"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "Ou exclusif"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Activité"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Transition"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Transitions"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Instance"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Instances"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Transition"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Transitions"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Élément"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Éléments"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Workflow"
-340
View File
@@ -1,340 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "Geen werkgang verzoek gedefinieert!"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "Geen werkgang gedefinieert!"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Activiteiten"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Middel model"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "Bij maken"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Werkgang start"
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Werkgang stop"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Inkomende overgangen"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Verzoeken"
#, fuzzy
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr "Methode"
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Uitgaande overgangen"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Signaal (subwerkgang.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Deel modus"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr ""
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Subwerkgang"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Werkgang"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Overloop"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "Middel ID"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Middel model"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Status"
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Overgangen"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "Gebruiker ID"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Werkgang"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Handelingen"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Bron activiteit"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Bestemming activiteit"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Voorwaarde"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Benodigde groep"
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Verzoeken"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Signaal (knop naam)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr ""
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Starter type"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Verzoek"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Overgang"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Bestemming verzoek"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Model"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "Middel ID"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Handeling"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Activiteit"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Verzoek"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Naam"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Status"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Subwerkgang"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Activiteiten"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Verzoeken"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Overgangen"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Werkgangen"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Handelingen"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Activiteiten"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Verzoeken"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Overgangen"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Werkgang"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Werkgangen"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Handelingen"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Werkgang"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Werkgang activiteit"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Werkgang verzoek"
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Werkgang overgang"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Werkgang overgan - Verzoek"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Werkgang starter"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "Werkgang handeling"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "En"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr "Exof"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "En"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "Of"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr "Exof"
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Activiteit"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Overgang"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Overgangen"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Verzoek"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Verzoeken"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Overgang"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Overgangen"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Handeling"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Handelingen"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Werkgang"
-339
View File
@@ -1,339 +0,0 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:workflow.instance:0"
msgid "No workflow instance defined!"
msgstr "Не определен экземпляр процесса!"
msgctxt "error:workflow:0"
msgid "No workflow defined!"
msgstr "Не определен процесс!"
msgctxt "field:workflow,activities:0"
msgid "Activities"
msgstr "Активность"
msgctxt "field:workflow,model:0"
msgid "Resource Model"
msgstr "Ресурс Шаблон"
msgctxt "field:workflow,name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow,on_create:0"
msgid "On Create"
msgstr "Создать"
msgctxt "field:workflow,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.activity,flow_start:0"
msgid "Flow Start"
msgstr "Запустить поток "
msgctxt "field:workflow.activity,flow_stop:0"
msgid "Flow Stop"
msgstr "Остановить поток"
msgctxt "field:workflow.activity,in_transitions:0"
msgid "Incoming transitions"
msgstr "Входящая операция"
msgctxt "field:workflow.activity,join_mode:0"
msgid "Join Mode"
msgstr "Режим объединения"
msgctxt "field:workflow.activity,method:0"
msgid "Method"
msgstr ""
msgctxt "field:workflow.activity,name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.activity,out_transitions:0"
msgid "Outgoing transitions"
msgstr "Исходящая операция"
msgctxt "field:workflow.activity,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.activity,signal_send:0"
msgid "Signal (subflow.*)"
msgstr "Сигнал (подпроцесс.*)"
msgctxt "field:workflow.activity,split_mode:0"
msgid "Split Mode"
msgstr "Режим совмещения"
msgctxt "field:workflow.activity,stop_other:0"
msgid "Stop Other"
msgstr ""
msgctxt "field:workflow.activity,subflow:0"
msgid "Subflow"
msgstr "Подпоток"
msgctxt "field:workflow.activity,workflow:0"
msgid "Workflow"
msgstr "Ход работ (WorkFlow)"
msgctxt "field:workflow.instance,overflows:0"
msgid "Overflow"
msgstr "Переполнение"
msgctxt "field:workflow.instance,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.instance,res_id:0"
msgid "Resource ID"
msgstr "Ресурс ID"
msgctxt "field:workflow.instance,res_type:0"
msgid "Resource Model"
msgstr "Ресурс Шаблон"
msgctxt "field:workflow.instance,state:0"
msgid "State"
msgstr "Состояние"
msgctxt "field:workflow.instance,transitions:0"
msgid "Transitions"
msgstr "Резервный счет"
msgctxt "field:workflow.instance,uid:0"
msgid "User ID"
msgstr "Пользователь ID"
msgctxt "field:workflow.instance,workflow:0"
msgid "Workflow"
msgstr "Ход работ (WorkFlow)"
msgctxt "field:workflow.instance,workitems:0"
msgid "Workitems"
msgstr "Рабочий пункт"
msgctxt "field:workflow.transition,act_from:0"
msgid "Source Activity"
msgstr "Источник действия"
msgctxt "field:workflow.transition,act_to:0"
msgid "Destination Activity"
msgstr "Получатель действия"
msgctxt "field:workflow.transition,condition:0"
msgid "Condition"
msgstr "Состояние"
msgctxt "field:workflow.transition,group:0"
msgid "Group Required"
msgstr "Требуется группа"
msgctxt "field:workflow.transition,instances:0"
msgid "Instances"
msgstr "Резервный счет"
msgctxt "field:workflow.transition,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.transition,signal:0"
msgid "Signal (button Name)"
msgstr "Сигнал (наименование кнопки)"
msgctxt "field:workflow.transition,trigger_ids:0"
msgid "Trigger Expr ID"
msgstr ""
msgctxt "field:workflow.transition,trigger_model:0"
msgid "Trigger Type"
msgstr "Тип триггера"
msgctxt "field:workflow.transition-workflow.instance,inst_id:0"
msgid "Instance"
msgstr "Экземпляр"
msgctxt "field:workflow.transition-workflow.instance,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.transition-workflow.instance,trans_id:0"
msgid "Transition"
msgstr "Переход"
msgctxt "field:workflow.trigger,instance:0"
msgid "Destination Instance"
msgstr "Экземпляр получатель"
msgctxt "field:workflow.trigger,model:0"
msgid "Model"
msgstr "Шаблон"
msgctxt "field:workflow.trigger,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.trigger,res_id:0"
msgid "Resource ID"
msgstr "Ресурс ID"
msgctxt "field:workflow.trigger,workitem:0"
msgid "Workitem"
msgstr "Пункт процесса"
msgctxt "field:workflow.workitem,activity:0"
msgid "Activity"
msgstr "Деятельность"
msgctxt "field:workflow.workitem,instance:0"
msgid "Instance"
msgstr "Экземпляр"
msgctxt "field:workflow.workitem,rec_name:0"
msgid "Name"
msgstr "Наименование"
msgctxt "field:workflow.workitem,state:0"
msgid "State"
msgstr "Состояние"
msgctxt "field:workflow.workitem,subflow:0"
msgid "Subflow"
msgstr "Подпоток"
msgctxt "model:ir.action,name:act_activity_form"
msgid "Activities"
msgstr "Активность"
msgctxt "model:ir.action,name:act_instance_form"
msgid "Instances"
msgstr "Экземпляры"
msgctxt "model:ir.action,name:act_transition_form"
msgid "Transitions"
msgstr "Переходы"
msgctxt "model:ir.action,name:act_workflow_form"
msgid "Workflows"
msgstr "Процессы"
msgctxt "model:ir.action,name:act_workitem_form"
msgid "Workitems"
msgstr "Пункт процесса"
msgctxt "model:ir.ui.menu,name:menu_activity_form"
msgid "Activities"
msgstr "Активность"
msgctxt "model:ir.ui.menu,name:menu_instance_form"
msgid "Instances"
msgstr "Экземпляры"
msgctxt "model:ir.ui.menu,name:menu_transition_form"
msgid "Transitions"
msgstr "Переходы"
msgctxt "model:ir.ui.menu,name:menu_workflow"
msgid "Workflow"
msgstr "Ход работ (WorkFlow)"
msgctxt "model:ir.ui.menu,name:menu_workflow_form"
msgid "Workflows"
msgstr "Процессы"
msgctxt "model:ir.ui.menu,name:menu_workitem_form"
msgid "Workitems"
msgstr "Рабочий пункт"
msgctxt "model:workflow,name:0"
msgid "Workflow"
msgstr "Ход работ (WorkFlow)"
msgctxt "model:workflow.activity,name:0"
msgid "Workflow activity"
msgstr "Активный процесс"
msgctxt "model:workflow.instance,name:0"
msgid "Workflow instance"
msgstr "Экземпляр процесса "
msgctxt "model:workflow.transition,name:0"
msgid "Workflow transition"
msgstr "Переход процесса"
msgctxt "model:workflow.transition-workflow.instance,name:0"
msgid "Workflow Transition - Instance"
msgstr "Процесс переход - экземпляр"
msgctxt "model:workflow.trigger,name:0"
msgid "Workflow trigger"
msgstr "Триггер процесса"
msgctxt "model:workflow.workitem,name:0"
msgid "Workflow workitem"
msgstr "Точка процесса"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "And"
msgstr "и"
msgctxt "selection:workflow.activity,join_mode:0"
msgid "Xor"
msgstr ""
msgctxt "selection:workflow.activity,split_mode:0"
msgid "And"
msgstr "и"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Or"
msgstr "или"
msgctxt "selection:workflow.activity,split_mode:0"
msgid "Xor"
msgstr ""
msgctxt "view:workflow.activity:0"
msgid "Activity"
msgstr "Деятельность"
msgctxt "view:workflow.activity:0"
msgid "Transition"
msgstr "Переход"
msgctxt "view:workflow.activity:0"
msgid "Transitions"
msgstr "Переходы"
msgctxt "view:workflow.instance:0"
msgid "Instance"
msgstr "Экземпляр"
msgctxt "view:workflow.instance:0"
msgid "Instances"
msgstr "Экземпляры"
msgctxt "view:workflow.transition:0"
msgid "Transition"
msgstr "Переход"
msgctxt "view:workflow.transition:0"
msgid "Transitions"
msgstr "Переходы"
msgctxt "view:workflow.workitem:0"
msgid "Workitem"
msgstr "Пункт процесса"
msgctxt "view:workflow.workitem:0"
msgid "Workitems"
msgstr "Пункты процесса"
msgctxt "view:workflow:0"
msgid "Workflow"
msgstr "Ход работ (WorkFlow)"
-689
View File
@@ -1,689 +0,0 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields
from trytond.report import Report
from trytond.backend import TableHandler
from trytond.pyson import Eval, Bool
from trytond.transaction import Transaction
from trytond.pool import Pool
class Workflow(ModelSQL, ModelView):
"Workflow"
_name = "workflow"
_table = "wkf"
_description = __doc__
name = fields.Char('Name', required=True, translate=True)
model = fields.Char('Resource Model', required=True, select=True)
on_create = fields.Boolean('On Create', select=True)
activities = fields.One2Many('workflow.activity', 'workflow',
'Activities')
def __init__(self):
super(Workflow, self).__init__()
self._error_messages.update({
'no_workflow_defined': 'No workflow defined!',
})
def init(self, module_name):
super(Workflow, self).init(module_name)
cursor = Transaction().cursor
table = TableHandler(cursor, self, module_name)
# Migration from 1.2 rename osv into model
if table.column_exist('osv'):
cursor.execute('UPDATE "' + self._table + '" ' \
'SET model = osv')
table.drop_column('osv', exception=True)
def default_on_create(self):
return 1
Workflow()
class WorkflowActivity(ModelSQL, ModelView):
"Workflow activity"
_name = "workflow.activity"
_table = "wkf_activity"
_description = __doc__
name = fields.Char('Name', required=True, translate=True)
workflow = fields.Many2One('workflow', 'Workflow', required=True,
select=True, ondelete='CASCADE')
split_mode = fields.Selection([
('XOR', 'Xor'),
('OR', 'Or'),
('AND', 'And'),
], 'Split Mode', required=True)
join_mode = fields.Selection([
('XOR', 'Xor'),
('AND', 'And'),
], 'Join Mode', required=True)
method = fields.Char('Method')
flow_start = fields.Boolean('Flow Start')
flow_stop = fields.Boolean('Flow Stop')
stop_other = fields.Boolean('Stop Other')
subflow = fields.Many2One('workflow', 'Subflow')
signal_send = fields.Char('Signal (subflow.*)')
out_transitions = fields.One2Many('workflow.transition', 'act_from',
'Outgoing transitions')
in_transitions = fields.One2Many('workflow.transition', 'act_to',
'Incoming transitions')
def init(self, module_name):
super(WorkflowActivity, self).init(module_name)
cursor = Transaction().cursor
table = TableHandler(cursor, self, module_name)
# Migration from 2.0
if table.column_exist('kind'):
cursor.execute('UPDATE "%s" SET stop_other = %%s '
"WHERE kind='stopall'" % self._table, (True,))
table.drop_column('kind', exception=True)
def default_kind(self):
return 'dummy'
def default_join_mode(self):
return 'XOR'
def default_split_mode(self):
return 'XOR'
def default_flow_start(self):
return False
def default_flow_stop(self):
return False
def default_stop_other(self):
return False
WorkflowActivity()
class WorkflowTransition(ModelSQL, ModelView):
"Workflow transition"
_table = "wkf_transition"
_name = "workflow.transition"
_rec_name = 'signal'
_description = __doc__
trigger_model = fields.Char('Trigger Type')
trigger_ids = fields.Char('Trigger Expr ID', states={
'required': Bool(Eval('trigger_model')),
}, depends=['trigger_model'])
signal = fields.Char('Signal (button Name)')
group = fields.Many2One('res.group', 'Group Required')
condition = fields.Char('Condition', required=True)
act_from = fields.Many2One('workflow.activity', 'Source Activity',
required=True, select=True, ondelete='CASCADE')
act_to = fields.Many2One('workflow.activity', 'Destination Activity',
required=True, select=True, ondelete='CASCADE')
instances = fields.Many2Many('workflow.transition-workflow.instance',
'trans_id', 'inst_id', 'Instances')
def init(self, module_name):
cursor = Transaction().cursor
super(WorkflowTransition, self).init(module_name)
# Migration from 2.0: condition is a method name
cursor.execute('UPDATE "%s" SET "condition" = %%s '
'WHERE "condition" = %%s' % self._table, ('', 'True'))
def default_condition(self):
return ''
WorkflowTransition()
class WorkflowInstance(ModelSQL, ModelView):
"Workflow instance"
_table = "wkf_instance"
_name = "workflow.instance"
_rec_name = 'res_type'
_description = __doc__
workflow = fields.Many2One('workflow', 'Workflow', ondelete="RESTRICT",
select=True)
uid = fields.Integer('User ID')
res_id = fields.Integer('Resource ID', required=True, select=True)
res_type = fields.Char('Resource Model', required=True, select=True)
state = fields.Char('State', required=True, select=True)
overflows = fields.One2Many('workflow.workitem', 'subflow',
'Overflow')
transitions = fields.Many2Many('workflow.transition-workflow.instance',
'inst_id', 'trans_id', 'Transitions')
workitems = fields.One2Many('workflow.workitem', 'instance', 'Workitems')
def __init__(self):
super(WorkflowInstance, self).__init__()
self._error_messages.update({
'no_instance_defined': 'No workflow instance defined!',
})
for i in ('create', 'write', 'delete', 'copy'):
del self._rpc[i]
#TODO add a constraint to have only one active instance by resource
def init(self, module_name):
super(WorkflowInstance, self).init(module_name)
table = TableHandler(Transaction().cursor, self, module_name)
table.index_action(['res_id', 'res_type', 'state'], 'add')
table.index_action(['res_id', 'workflow'], 'add')
def fields_get(self, fields_names=None):
res = super(WorkflowInstance, self).fields_get(
fields_names=fields_names)
for field in res:
res[field]['readonly'] = True
return res
def create(self, values):
pool = Pool()
activity_obj = pool.get('workflow.activity')
workitem_obj = pool.get('workflow.workitem')
instance_id = super(WorkflowInstance, self).create(values)
if 'workflow' in values:
with Transaction().set_user(0):
activity_ids = activity_obj.search([
('flow_start', '=', True),
('workflow', '=', values['workflow']),
])
for activity_id in activity_ids:
workitem_obj.create({
'activity': activity_id,
'instance': instance_id,
'state': 'active',
})
instance = self.browse(instance_id)
self.update(instance)
return instance_id
def update(self, instance):
'''
'''
pool = Pool()
workitem_obj = pool.get('workflow.workitem')
for workitem in instance.workitems:
workitem_obj.process(workitem)
instance = self.browse(instance.id)
return self._update_end(instance)
def validate(self, instance, signal, force_running=False):
'''
'''
pool = Pool()
workitem_obj = pool.get('workflow.workitem')
for workitem in instance.workitems:
workitem_obj.process(workitem, signal=signal,
force_running=force_running)
instance = self.browse(instance.id)
return self._update_end(instance)
def _update_end(self, instance):
pool = Pool()
workitem_obj = pool.get('workflow.workitem')
res = True
for workitem in instance.workitems:
if (workitem.state != 'complete') \
or not workitem.activity.flow_stop:
res = False
break
if res:
act_names = set()
for workitem in instance.workitems:
act_names.add(workitem.activity.name)
with Transaction().set_user(0):
self.write(instance.id, {
'state': 'complete',
})
workitem_ids = workitem_obj.search([
('subflow', '=', instance.id),
])
workitem_obj.write(workitem_ids, {
'state': 'complete',
})
for workitem in workitem_obj.browse(workitem_ids):
for act_name in act_names:
self.validate(workitem.instance,
signal='subflow.' + act_name)
return res
WorkflowInstance()
class WorkflowTransitionInstance(ModelSQL):
"Workflow Transition - Instance"
_name = 'workflow.transition-workflow.instance'
_table = 'wkf_witm_trans'
_description = __doc__
trans_id = fields.Many2One('workflow.transition', 'Transition',
ondelete='CASCADE', select=True, required=True)
inst_id = fields.Many2One('workflow.instance', 'Instance',
ondelete='CASCADE', select=True, required=True)
def __init__(self):
super(WorkflowTransitionInstance, self).__init__()
for i in ('create', 'write', 'delete', 'copy'):
del self._rpc[i]
def fields_get(self, fields_names=None):
res = super(WorkflowTransitionInstance, self).fields_get(
fields_names=fields_names)
for field in res:
res[field]['readonly'] = True
return res
WorkflowTransitionInstance()
class WorkflowWorkitem(ModelSQL, ModelView):
"Workflow workitem"
_table = "wkf_workitem"
_name = "workflow.workitem"
_rec_name = 'state'
_description = __doc__
activity = fields.Many2One('workflow.activity', 'Activity',
required=True, ondelete="CASCADE", select=True)
subflow = fields.Many2One('workflow.instance', 'Subflow',
ondelete="CASCADE", select=True)
instance = fields.Many2One('workflow.instance', 'Instance',
required=True, ondelete="CASCADE", select=True)
state = fields.Char('State', select=True)
def __init__(self):
super(WorkflowWorkitem, self).__init__()
for i in ('create', 'write', 'delete', 'copy'):
del self._rpc[i]
def fields_get(self, fields_names=None):
res = super(WorkflowWorkitem, self).fields_get(
fields_names=fields_names)
for field in res:
res[field]['readonly'] = True
return res
def create(self, values):
workitem_id = super(WorkflowWorkitem, self).create(values)
with Transaction().set_user(0):
workitem = self.browse(workitem_id)
self.process(workitem)
return workitem_id
def process(self, workitem, signal=None, force_running=False):
'''
Process a workitem
:param workitem: a BrowseRecord of the workflow.workitem
:param signal: the signal
:param force_running: a boolean
'''
pool = Pool()
trigger_obj = pool.get('workflow.trigger')
activity = workitem.activity
triggers = False
if workitem.state == 'active':
triggers = True
if not self._execute(workitem, activity):
return False
if workitem.state == 'complete' or force_running:
res = self._split_test(workitem, activity.split_mode, signal)
triggers = triggers and not res
if triggers:
trigger_transitions = (t for t in activity.out_transitions
if t.trigger_model)
for transition in trigger_transitions:
model_obj = pool.get(workitem.instance.res_type)
model_ids_fct = getattr(model_obj, transition.trigger_ids)
ids = model_ids_fct(model_obj.browse(workitem.instance.res_id))
with Transaction().set_user(0):
for res_id in ids:
trigger_obj.create({
'model': transition.trigger_model,
'res_id': res_id,
'instance': workitem.instance.id,
'workitem': workitem.id,
})
return True
def _state_set(self, workitem, state):
self.write(workitem.id, {
'state': state,
})
#XXX must be changed with a cache reset on BrowseRecord
workitem._data[workitem.id]['state'] = state
def _execute(self, workitem, activity):
pool = Pool()
instance_obj = pool.get('workflow.instance')
#send a signal to overflow
if (workitem.state == 'active') and activity.signal_send:
for overflow in workitem.overflows:
instance_obj.validate(overflow.instance, activity.signal_send,
force_running=True)
if workitem.state == 'active':
self._state_set(workitem, 'running')
if activity.stop_other:
ids = self.search([
('instance', '=', workitem.instance.id),
('id', '!=', workitem.id),
])
#XXX check if delete must not be replace by _state_set 'complete'
with Transaction().set_user(0):
self.delete(ids)
if activity.method:
id_new = self._execute_action(workitem, activity)
else:
id_new = None
if activity.subflow:
if activity.method and id_new:
with Transaction().set_user(0):
instance_id = instance_obj.search([
('res_id', '=', id_new),
('workflow', '=', activity.subflow.id),
], limit=1)[0]
elif not activity.method:
instance_id = instance_obj.create({
'res_type': workitem.instance.res_type,
'res_id': workitem.instance.res_id,
'workflow': activity.subflow.id,
})
else:
with Transaction().set_user(0):
self.delete(workitem.id)
return False
self.write(workitem.id, {
'subflow': instance_id,
})
#XXX must be changed with a cache reset on BrowseRecord
workitem._data[workitem.id]['subflow'] = instance_id
else:
self._state_set(workitem, 'complete')
elif workitem.state == 'running' and activity.subflow:
if workitem.subflow.state == 'complete':
self._state_set(workitem, 'complete')
return True
def _execute_action(self, workitem, activity):
model_obj = Pool().get(workitem.instance.res_type)
wkf_action = getattr(model_obj, activity.method)
return wkf_action(model_obj.browse(workitem.instance.res_id))
def _activate_transition(self, workitem, transition, signal):
pool = Pool()
user_obj = pool.get('res.user')
if transition.signal:
if signal != transition.signal:
return False
if transition.group and Transaction().user != 0:
user_groups = user_obj.get_groups()
if transition.group.id not in user_groups:
return False
model_obj = pool.get(workitem.instance.res_type)
if transition.condition:
test_fct = getattr(model_obj, transition.condition)
return test_fct(model_obj.browse(workitem.instance.res_id))
else:
return True
def _split_test(self, workitem, split_mode, signal=None):
pool = Pool()
instance_obj = pool.get('workflow.instance')
test = False
transitions = []
if split_mode == 'XOR' or split_mode == 'OR':
for transition in workitem.activity.out_transitions:
if self._activate_transition(workitem, transition, signal):
test = True
transitions.append(transition)
if split_mode == 'XOR':
break
else:
test = True
for transition in workitem.activity.out_transitions:
if not self._activate_transition(workitem, transition, signal):
test = False
break
if transition.id not in \
[x.id for x in workitem.instance.transitions]:
transitions.append(transition)
if test and len(transitions):
with Transaction().set_user(0):
instance_obj.write(workitem.instance.id, {
'transitions': [('add', [x.id for x in transitions])],
})
instance = workitem.instance
self.delete(workitem.id)
for transition in transitions:
self._join_test(transition, instance)
return True
return False
def _join_test(self, transition, instance):
pool = Pool()
instance_obj = pool.get('workflow.instance')
activity = transition.act_to
if activity.join_mode == 'XOR':
self.create({
'activity': activity.id,
'instance': instance.id,
'state': 'active',
})
with Transaction().set_user(0):
instance_obj.write(instance.id, {
'transitions': [('unlink', transition.id)],
})
else:
delete = True
for transition in activity.in_transitions:
if instance.id not in \
[x.id for x in transition.instances]:
delete = False
break
if delete:
with Transaction().set_user(0):
instance_obj.write(instance.id, {
'transitions': [('unlink', [x.id
for x in activity.in_transitions])],
})
self.create({
'activity': activity.id,
'instance': instance.id,
'state': 'active',
})
WorkflowWorkitem()
class WorkflowTrigger(ModelSQL, ModelView):
"Workflow trigger"
_table = "wkf_trigger"
_name = "workflow.trigger"
_description = __doc__
res_id = fields.Integer('Resource ID', required=True)
model = fields.Char('Model')
instance = fields.Many2One('workflow.instance',
'Destination Instance', ondelete="CASCADE")
workitem = fields.Many2One('workflow.workitem', 'Workitem',
required=True, ondelete="CASCADE")
def __init__(self):
super(WorkflowTrigger, self).__init__()
for i in ('create', 'write', 'delete', 'copy'):
del self._rpc[i]
def init(self, module_name):
super(WorkflowTrigger, self).init(module_name)
table = TableHandler(Transaction().cursor, self, module_name)
table.index_action(['res_id', 'model'], 'add')
def fields_get(self, fields_names=None):
res = super(WorkflowTrigger, self).fields_get(
fields_names=fields_names)
for field in res:
res[field]['readonly'] = True
return res
WorkflowTrigger()
class InstanceGraph(Report):
_name = 'workflow.instance.graph'
def execute(self, ids, datas):
import pydot
pool = Pool()
lang_obj = pool.get('ir.lang')
workflow_obj = pool.get('workflow')
instance_obj = pool.get('workflow.instance')
lang_id = lang_obj.search([
('code', '=', Transaction().language),
], limit=1)[0]
lang = lang_obj.browse(lang_id)
workflow_id = workflow_obj.search([
('model', '=', datas['model']),
], limit=1)
if not workflow_id:
workflow_obj.raise_user_error('no_workflow_defined')
workflow_id = workflow_id[0]
workflow = workflow_obj.browse(workflow_id)
instance_id = instance_obj.search([
('res_id', '=', datas['id']),
('workflow', '=', workflow.id),
], order=[('id', 'DESC')], limit=1)
if not instance_id:
instance_obj.raise_user_error('no_instance_defined')
instance_id = instance_id[0]
title = "Workflow: %s" % (workflow.name.encode('ascii', 'replace'),)
if pydot.__version__ == '1.0.2':
# version 1.0.2 doesn't quote correctly label on Dot object
title = '"' + title + '"'
graph = pydot.Dot(fontsize='16',
label=title)
graph.set('center', '1')
graph.set('ratio', 'auto')
if lang.direction == 'ltr':
if hasattr(graph, 'set_rankdir'):
graph.set_rankdir('LR')
else:
graph.set('rankdir', 'LR')
else:
if hasattr(graph, 'set_rankdir'):
graph.set_rankdir('RL')
else:
graph.set('rankdir', 'RL')
self.graph_instance_get(graph, instance_id, datas.get('nested', False))
data = graph.create(prog='dot', format='png')
return ('png', buffer(data), False, workflow.name)
def graph_instance_get(self, graph, instance_id, nested=False):
pool = Pool()
instance_obj = pool.get('workflow.instance')
instance = instance_obj.browse(instance_id)
self.graph_get(graph, instance.workflow.id, nested,
self.workitem_get(instance.id))
def workitem_get(self, instance_id):
res = {}
pool = Pool()
workitem_obj = pool.get('workflow.workitem')
workitem_ids = workitem_obj.search([
('instance', '=', instance_id),
])
workitems = workitem_obj.browse(workitem_ids)
for workitem in workitems:
res.setdefault(workitem.activity.id, 0)
res[workitem.activity.id] += 1
if workitem.subflow:
res.update(self.workitem_get(workitem.subflow.id))
return res
def graph_get(self, graph, workflow_id, nested=False, workitem=None):
import pydot
if workitem is None:
workitem = {}
pool = Pool()
activity_obj = pool.get('workflow.activity')
workflow_obj = pool.get('workflow')
transition_obj = pool.get('workflow.transition')
activity_ids = activity_obj.search([
('workflow', '=', workflow_id),
])
id2activities = {}
actfrom = {}
actto = {}
activities = activity_obj.browse(activity_ids)
start = 0
stop = {}
for activity in activities:
if activity.flow_start:
start = activity.id
if activity.flow_stop:
stop['subflow.' + activity.name] = activity.id
id2activities[activity.id] = activity
if activity.subflow and nested:
workflow = workflow_obj.browse(activity.subflow.id)
subgraph = pydot.Cluster('subflow' + str(workflow.id),
fontsize='12',
label="Subflow: " + activity.name.encode('ascii', 'replace'))
(substart, substop) = self.graph_get(subgraph, workflow.id,
nested, workitem)
graph.add_subgraph(subgraph)
actfrom[activity.id] = substart
actto[activity.id] = substop
else:
args = {}
args['label'] = activity.name.encode('ascii', 'replace')
args['fontsize'] = '10'
if activity.flow_start or activity.flow_stop:
args['style'] = 'filled'
args['color'] = 'lightgrey'
if activity.subflow:
args['shape'] = 'box'
else:
args['shape'] = 'octagon'
if activity.id in workitem:
args['label'] += '\\nx ' + str(workitem[activity.id])
args['color'] = 'red'
graph.add_node(pydot.Node(activity.id, **args))
actfrom[activity.id] = (activity.id, {})
actto[activity.id] = (activity.id, {})
transition_ids = transition_obj.search([
('act_from', 'in', [x.id for x in activities]),
])
transitions = transition_obj.browse(transition_ids)
for transition in transitions:
args = {}
args['label'] = ' '
if transition.condition:
args['label'] += transition.condition
if transition.signal:
args['label'] += '\\n' + str(transition.signal)
args['style'] = 'bold'
if id2activities[transition.act_from.id].split_mode == 'AND':
args['arrowtail'] = 'box'
elif id2activities[transition.act_from.id].split_mode == 'OR':
args['arrowtail'] = 'inv'
if id2activities[transition.act_to.id].join_mode == 'AND':
args['arrowhead'] = 'crow'
activity_from = actfrom[transition.act_from.id][1].get(
transition.signal, actfrom[transition.act_from.id][0])
activity_to = actto[transition.act_to.id][1].get(
transition.signal, actto[transition.act_to.id][0])
graph.add_edge(pydot.Edge(str(activity_from), str(activity_to),
fontsize='10', **args))
return ((start, {}), (stop.values()[0], stop))
InstanceGraph()
-357
View File
@@ -1,357 +0,0 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<menuitem name="Workflow" id="menu_workflow"
parent="ir.menu_administration"/>
<record model="ir.ui.menu-res.group" id="menu_workflow_group_admin">
<field name="menu" ref="menu_workflow"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.ui.view" id="workflow_view_form">
<field name="model">workflow</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Workflow" col="6">
<label name="name"/>
<field name="name"/>
<label name="model"/>
<field name="model"/>
<label name="on_create"/>
<field name="on_create"/>
<field name="activities" colspan="6"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="workflow_view_tree">
<field name="model">workflow</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Workflow">
<field name="name"/>
<field name="model"/>
<field name="on_create"/>
</tree>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_workflow_form">
<field name="name">Workflows</field>
<field name="res_model">workflow</field>
</record>
<record model="ir.action.act_window.view"
id="act_workflow_form_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="workflow_view_tree"/>
<field name="act_window" ref="act_workflow_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_workflow_form_view2">
<field name="sequence" eval="2"/>
<field name="view" ref="workflow_view_form"/>
<field name="act_window" ref="act_workflow_form"/>
</record>
<menuitem parent="menu_workflow"
action="act_workflow_form" id="menu_workflow_form"/>
<record model="ir.ui.menu-res.group" id="menu_workflow_form_group_admin">
<field name="menu" ref="menu_workflow"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.model.access" id="access_workflow">
<field name="model" search="[('model', '=', 'workflow')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_workflow_admin">
<field name="model" search="[('model', '=', 'workflow')]"/>
<field name="group" ref="res.group_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="activity_view_form">
<field name="model">workflow.activity</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Activity">
<label name="name"/>
<field name="name" colspan="3"/>
<label name="workflow"/>
<field name="workflow"/>
<label name="method"/>
<field name="method"/>
<label name="subflow"/>
<field name="subflow"/>
<label name="signal_send"/>
<field name="signal_send"/>
<newline/>
<label name="flow_start"/>
<field name="flow_start"/>
<label name="flow_stop"/>
<field name="flow_stop"/>
<label name="join_mode"/>
<field name="join_mode"/>
<label name="split_mode"/>
<field name="split_mode"/>
<field name="out_transitions" colspan="4"/>
<field name="in_transitions" colspan="4"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="activity_view_tree">
<field name="model">workflow.activity</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Activity">
<field name="name"/>
<field name="workflow"/>
<field name="method"/>
<field name="flow_start"/>
<field name="flow_stop"/>
</tree>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_activity_form">
<field name="name">Activities</field>
<field name="res_model">workflow.activity</field>
</record>
<record model="ir.action.act_window.view"
id="act_activity_form_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="activity_view_tree"/>
<field name="act_window" ref="act_activity_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_activity_form_view2">
<field name="sequence" eval="2"/>
<field name="view" ref="activity_view_form"/>
<field name="act_window" ref="act_activity_form"/>
</record>
<menuitem parent="menu_workflow"
action="act_activity_form" id="menu_activity_form"/>
<record model="ir.ui.menu-res.group" id="menu_activity_form_group_admin">
<field name="menu" ref="menu_activity_form"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.model.access" id="access_workflow_activity">
<field name="model" search="[('model', '=', 'workflow.activity')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_workflow_activity_admin">
<field name="model" search="[('model', '=', 'workflow.activity')]"/>
<field name="group" ref="res.group_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="transition_view_form">
<field name="model">workflow.transition</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Transition">
<label name="act_from"/>
<field name="act_from"/>
<label name="act_to"/>
<field name="act_to"/>
<label name="condition"/>
<field name="condition" colspan="3"/>
<label name="signal"/>
<field name="signal"/>
<label name="group"/>
<field name="group"/>
<label name="trigger_model"/>
<field name="trigger_model"/>
<label name="trigger_ids"/>
<field name="trigger_ids"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="transition_view_tree">
<field name="model">workflow.transition</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Transitions">
<field name="act_from"/>
<field name="act_to"/>
<field name="signal"/>
<field name="group"/>
<field name="condition"/>
<field name="trigger_model"/>
<field name="trigger_ids"/>
</tree>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_transition_form">
<field name="name">Transitions</field>
<field name="res_model">workflow.transition</field>
</record>
<record model="ir.action.act_window.view"
id="act_transition_form_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="transition_view_tree"/>
<field name="act_window" ref="act_transition_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_transition_form_view2">
<field name="sequence" eval="2"/>
<field name="view" ref="transition_view_form"/>
<field name="act_window" ref="act_transition_form"/>
</record>
<menuitem parent="menu_workflow"
action="act_transition_form" id="menu_transition_form"/>
<record model="ir.ui.menu-res.group" id="menu_transition_form_group_admin">
<field name="menu" ref="menu_transition_form"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.model.access" id="access_workflow_transition">
<field name="model" search="[('model', '=', 'workflow.transition')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_workflow_transition_admin">
<field name="model" search="[('model', '=', 'workflow.transition')]"/>
<field name="group" ref="res.group_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="instance_view_form">
<field name="model">workflow.instance</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Instance">
<label name="workflow"/>
<field name="workflow"/>
<label name="uid"/>
<field name="uid"/>
<label name="res_id"/>
<field name="res_id"/>
<label name="res_type"/>
<field name="res_type"/>
<label name="state"/>
<field name="state"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="instance_view_tree">
<field name="model">workflow.instance</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Instances">
<field name="workflow"/>
<field name="uid"/>
<field name="res_id"/>
<field name="res_type"/>
<field name="state"/>
</tree>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_instance_form">
<field name="name">Instances</field>
<field name="res_model">workflow.instance</field>
</record>
<record model="ir.action.act_window.view"
id="act_instance_form_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="instance_view_tree"/>
<field name="act_window" ref="act_instance_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_instance_form_view2">
<field name="sequence" eval="2"/>
<field name="view" ref="instance_view_form"/>
<field name="act_window" ref="act_instance_form"/>
</record>
<menuitem parent="menu_workflow"
action="act_instance_form" id="menu_instance_form"/>
<record model="ir.ui.menu-res.group" id="menu_instance_form_group_admin">
<field name="menu" ref="menu_instance_form"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.ui.view" id="workitem_view_form">
<field name="model">workflow.workitem</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Workitem">
<label name="activity"/>
<field name="activity"/>
<label name="subflow"/>
<field name="subflow"/>
<label name="instance"/>
<field name="instance"/>
<label name="state"/>
<field name="state"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="workitem_view_tree">
<field name="model">workflow.workitem</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Workitems">
<field name="activity"/>
<field name="subflow"/>
<field name="instance"/>
<field name="state"/>
</tree>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_workitem_form">
<field name="name">Workitems</field>
<field name="res_model">workflow.workitem</field>
</record>
<record model="ir.action.act_window.view"
id="act_workitem_form_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="workitem_view_tree"/>
<field name="act_window" ref="act_workitem_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_workitem_form_view2">
<field name="sequence" eval="2"/>
<field name="view" ref="workitem_view_form"/>
<field name="act_window" ref="act_workitem_form"/>
</record>
<menuitem parent="menu_workflow"
action="act_workitem_form" id="menu_workitem_form"/>
<record model="ir.ui.menu-res.group" id="menu_workitem_form_group_admin">
<field name="menu" ref="menu_workitem_form"/>
<field name="group" ref="res.group_admin"/>
</record>
</data>
</tryton>