Server actions have several types available, but executing arbitrary Python code is surely the most flexible one. Used wisely, it can provide power users with the capability to implement advanced business rules from the user interface, without the need to create specific addon modules to install that code.
We will demonstrate using this type of server actions by implementing one that sends reminder notifications to the followers of a Project task.
To create and try a Python code server action, follow these steps:
if not obj.date_deadline: raise Warning('Task has no deadline!') deadline_dt = datetime.datetime.strptime( obj.date_deadline, '%Y-%m-%d') delta = deadline_dt.date() - datetime.date.today() days = delta.days if days==0: msg = 'Task is due today.' elif days < 0: msg = 'Task is %d day(s) late.' % abs(days) else: msg = 'Task will be due in %d day(s).' % days obj.message_post(msg, subject='Reminder', subtype='mt_comment')
The Create server actions recipe provides a detailed explanation on how to create a server action in general. For this particular type of action, we need to pick the Execute Python Code option and then write the code to run the text area.
The code can have multiple lines, as is the case in our recipe, and it runs in a context that has available references to objects such as the current record object or the session user. The references available are described in the Create server actions recipe.
The used code computes the number of days from the current date until the deadline date, and uses that to prepare an appropriate notification message. The last line does the actual posting of the message in the task's message wall. The subtype='mt_comment'
argument is needed for e-mail notifications to be sent to the followers, just like when we use the New Message button. If no subtype is given, mt_note
is used as a default, posting an internal note without notification, as if we used the Log an internal note button.
Python code server actions are a powerful and flexible resource, but do have some limitations compared to the custom addon modules.
Since the Python code is evaluated at run time, in case of an error the stack trace is not so informative and it can be harder to debug. It is also not possible to insert a breakpoint in the code of a server action using the techniques shown in Chapter 7, Debugging and Automated Testing, so debugging needs to be done by using logging statements. Another concern is, when trying to track down the cause from a behavior in module code, you may miss that; it's probably caused by a server sction.
When carrying out a more intensive use of server actions, we can get complex interactions, so it is advised to plan properly and keep them organized.