def _select_objects(self, cr, uid, context=None):
model_pool = self.pool.get('ir.model')
- ids = model_pool.search(cr, uid, [('name', 'not ilike', '.')])
+ ids = model_pool.search(cr, uid, [], limit=None)
res = model_pool.read(cr, uid, ids, ['model', 'name'])
- return [(r['model'], r['name']) for r in res] + [('','')]
-
- def change_object(self, cr, uid, ids, copy_object, state, context=None):
- if state == 'object_copy' and copy_object:
- if context is None:
- context = {}
- model_pool = self.pool.get('ir.model')
- model = copy_object.split(',')[0]
- mid = model_pool.search(cr, uid, [('model','=',model)])
- return {
- 'value': {'srcmodel_id': mid[0]},
- 'context': context
- }
- else:
- return {}
+ return [(r['model'], r['name']) for r in res] + [('', '')]
+
+ def _get_states(self, cr, uid, context=None):
+ """ Override me in order to add new states in the server action. Please
+ note that the added key length should not be higher than already-existing
+ ones. """
+ return [('code', 'Execute Python Code'),
+ ('trigger', 'Trigger a Workflow Signal'),
+ ('client_action', 'Run a Client Action'),
+ ('object_create', 'Create or Copy a new Record'),
+ ('object_write', 'Write on a Record'),
+ ('multi', 'Execute several actions')]
+
+ def _get_states_wrapper(self, cr, uid, context=None):
+ return self._get_states(cr, uid, context)
- _name = 'ir.actions.server'
- _table = 'ir_act_server'
- _inherit = 'ir.actions.actions'
- _sequence = 'ir_actions_id_seq'
- _order = 'sequence,name'
_columns = {
'name': fields.char('Action Name', required=True, size=64, translate=True),
- 'condition' : fields.char('Condition', size=256, required=True,
- help="Condition that is tested before the action is executed, "
- "and prevent execution if it is not verified.\n"
- "Example: object.list_price > 5000\n"
- "It is a Python expression that can use the following values:\n"
- " - self: ORM model of the record on which the action is triggered\n"
- " - object or obj: browse_record of the record on which the action is triggered\n"
- " - pool: ORM model pool (i.e. self.pool)\n"
- " - time: Python time module\n"
- " - cr: database cursor\n"
- " - uid: current user id\n"
- " - context: current context"),
- 'state': fields.selection([
- ('client_action','Client Action'),
- ('dummy','Dummy'),
- ('loop','Iteration'),
- ('code','Python Code'),
- ('trigger','Trigger'),
- ('email','Email'),
- ('sms','SMS'),
- ('object_create','Create Object'),
- ('object_copy','Copy Object'),
- ('object_write','Write Object'),
- ('other','Multi Actions'),
- ], 'Action Type', required=True, size=32, help="Type of the Action that is to be executed"),
- 'code':fields.text('Python Code', help="Python code to be executed if condition is met.\n"
- "It is a Python block that can use the same values as for the condition field"),
- 'sequence': fields.integer('Sequence', help="Important when you deal with multiple actions, the execution order will be decided based on this, low number is higher priority."),
- 'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the object on which the action will work (read, write, create).", ondelete='cascade'),
- 'action_id': fields.many2one('ir.actions.actions', 'Client Action', help="Select the Action Window, Report, Wizard to be executed."),
- 'trigger_name': fields.selection(_select_signals, string='Trigger Signal', size=128, help="The workflow signal to trigger"),
- 'wkf_model_id': fields.many2one('ir.model', 'Target Object', help="The object that should receive the workflow signal (must have an associated workflow)"),
- 'trigger_obj_id': fields.many2one('ir.model.fields','Relation Field', help="The field on the current object that links to the target object record (must be a many2one, or an integer field with the record ID)"),
- 'email': fields.char('Email Address', size=512, help="Expression that returns the email address to send to. Can be based on the same values as for the condition field.\n"
- "Example: object.invoice_address_id.email, or 'me@example.com'"),
- 'subject': fields.char('Subject', size=1024, translate=True, help="Email subject, may contain expressions enclosed in double brackets based on the same values as those "
- "available in the condition field, e.g. `Hello [[ object.partner_id.name ]]`"),
- 'message': fields.text('Message', translate=True, help="Email contents, may contain expressions enclosed in double brackets based on the same values as those "
- "available in the condition field, e.g. `Dear [[ object.partner_id.name ]]`"),
- 'mobile': fields.char('Mobile No', size=512, help="Provides fields that be used to fetch the mobile number, e.g. you select the invoice, then `object.invoice_address_id.mobile` is the field which gives the correct mobile number"),
- 'sms': fields.char('SMS', size=160, translate=True),
- 'child_ids': fields.many2many('ir.actions.server', 'rel_server_actions', 'server_id', 'action_id', 'Other Actions'),
+ 'condition': fields.char('Condition',
+ help="Condition verified before executing the server action. If it "
+ "is not verified, the action will not be executed. The condition is "
+ "a Python expression, like 'object.list_price > 5000'. A void "
+ "condition is considered as always True. Help about python expression "
+ "is given in the help tab."),
+ 'state': fields.selection(_get_states_wrapper, 'Action To Do', required=True,
+ help="Type of server action. The following values are available:\n"
+ "- 'Execute Python Code': a block of python code that will be executed\n"
+ "- 'Trigger a Workflow Signal': send a signal to a workflow\n"
+ "- 'Run a Client Action': choose a client action to launch\n"
+ "- 'Create or Copy a new Record': create a new record with new values, or copy an existing record in your database\n"
+ "- 'Write on a Record': update the values of a record\n"
+ "- 'Execute several actions': define an action that triggers several other server actions\n"
+ "- 'Send Email': automatically send an email (available in email_template)"),
'usage': fields.char('Action Usage', size=32),
'type': fields.char('Action Type', size=32, required=True),
- 'srcmodel_id': fields.many2one('ir.model', 'Model', help="Object in which you want to create / write the object. If it is empty then refer to the Object field."),
- 'fields_lines': fields.one2many('ir.server.object.lines', 'server_id', 'Field Mappings.'),
- 'record_id':fields.many2one('ir.model.fields', 'Create Id', help="Provide the field name where the record id is stored after the create operations. If it is empty, you can not track the new record."),
- 'write_id':fields.char('Write Id', size=256, help="Provide the field name that the record id refers to for the write operation. If it is empty it will refer to the active id of the object."),
- 'loop_action':fields.many2one('ir.actions.server', 'Loop Action', help="Select the action that will be executed. Loop action will not be avaliable inside loop."),
- 'expression':fields.char('Loop Expression', size=512, help="Enter the field/expression that will return the list. E.g. select the sale order in Object, and you can have loop on the sales order line. Expression = `object.order_line`."),
- 'copy_object': fields.reference('Copy Of', selection=_select_objects, size=256),
+ # Generic
+ 'sequence': fields.integer('Sequence',
+ help="When dealing with multiple actions, the execution order is "
+ "based on the sequence. Low number means high priority."),
+ 'model_id': fields.many2one('ir.model', 'Base Model', required=True, ondelete='cascade',
+ help="Base model on which the server action runs."),
+ 'menu_ir_values_id': fields.many2one('ir.values', 'More Menu entry', readonly=True,
+ help='More menu entry.'),
+ # Client Action
+ 'action_id': fields.many2one('ir.actions.actions', 'Client Action',
+ help="Select the client action that has to be executed."),
+ # Python code
+ 'code': fields.text('Python Code',
+ help="Write Python code that the action will execute. Some variables are "
+ "available for use; help about pyhon expression is given in the help tab."),
+ # Workflow signal
+ 'use_relational_model': fields.selection([('base', 'Use the base model of the action'),
+ ('relational', 'Use a relation field on the base model')],
+ string='Target Model', required=True),
+ 'wkf_transition_id': fields.many2one('workflow.transition', string='Signal to Trigger',
+ help="Select the workflow signal to trigger."),
+ 'wkf_model_id': fields.many2one('ir.model', 'Target Model',
+ help="The model that will receive the workflow signal. Note that it should have a workflow associated with it."),
+ 'wkf_model_name': fields.related('wkf_model_id', 'model', type='char', string='Target Model Name', store=True, readonly=True),
+ 'wkf_field_id': fields.many2one('ir.model.fields', string='Relation Field',
+ oldname='trigger_obj_id',
+ help="The field on the current object that links to the target object record (must be a many2one, or an integer field with the record ID)"),
+ # Multi
+ 'child_ids': fields.many2many('ir.actions.server', 'rel_server_actions',
+ 'server_id', 'action_id',
+ string='Child Actions',
+ help='Child server actions that will be executed. Note that the last return returned action value will be used as global return value.'),
+ # Create/Copy/Write
+ 'use_create': fields.selection([('new', 'Create a new record in the Base Model'),
+ ('new_other', 'Create a new record in another model'),
+ ('copy_current', 'Copy the current record'),
+ ('copy_other', 'Choose and copy a record in the database')],
+ string="Creation Policy", required=True,
+ help=""),
+ 'crud_model_id': fields.many2one('ir.model', 'Target Model',
+ oldname='srcmodel_id',
+ help="Model for record creation / update. Set this field only to specify a different model than the base model."),
+ 'crud_model_name': fields.related('crud_model_id', 'model', type='char',
+ string='Create/Write Target Model Name',
+ store=True, readonly=True),
+ 'ref_object': fields.reference('Reference record', selection=_select_objects, size=128,
+ oldname='copy_object'),
+ 'link_new_record': fields.boolean('Attach the new record',
+ help="Check this if you want to link the newly-created record "
+ "to the current record on which the server action runs."),
+ 'link_field_id': fields.many2one('ir.model.fields', 'Link using field',
+ oldname='record_id',
+ help="Provide the field where the record id is stored after the operations."),
+ 'use_write': fields.selection([('current', 'Update the current record'),
+ ('expression', 'Update a record linked to the current record using python'),
+ ('other', 'Choose and Update a record in the database')],
+ string='Update Policy', required=True,
+ help=""),
+ 'write_expression': fields.char('Expression',
+ oldname='write_id',
+ help="Provide an expression that, applied on the current record, gives the field to update."),
+ 'fields_lines': fields.one2many('ir.server.object.lines', 'server_id',
+ string='Value Mapping',
+ help=""),
+
+ # Fake fields used to implement the placeholder assistant
+ 'model_object_field': fields.many2one('ir.model.fields', string="Field",
+ help="Select target field from the related document model.\n"
+ "If it is a relationship field you will be able to select "
+ "a target field at the destination of the relationship."),
+ 'sub_object': fields.many2one('ir.model', 'Sub-model', readonly=True,
+ help="When a relationship field is selected as first field, "
+ "this field shows the document model the relationship goes to."),
+ 'sub_model_object_field': fields.many2one('ir.model.fields', 'Sub-field',
+ help="When a relationship field is selected as first field, "
+ "this field lets you select the target field within the "
+ "destination document model (sub-model)."),
+ 'copyvalue': fields.char('Placeholder Expression', help="Final placeholder expression, to be copy-pasted in the desired template field."),
+ # Fake fields used to implement the ID finding assistant
+ 'id_object': fields.reference('Record', selection=_select_objects, size=128),
+ 'id_value': fields.char('Record ID'),
}
+
_defaults = {
- 'state': 'dummy',
+ 'state': 'code',
'condition': 'True',
'type': 'ir.actions.server',
'sequence': 5,