Example: Limit the number of hours a user can log per day
The following configuration allows to apply a restriction on the sum of hours a user can log in a single day, counting work logs in any issue.
Enforce work logs through transitions
First we need to enforce users to log all the work using transitions in our workflows, instead of using "Log Work" operation at the issue screen. To do it we will:
- Remove "Log Work" from actions menu:
Administration > Add-ons > Manage add-ons > Filter by "System" > Issue Operations Plugin > Disable module "View Issue Ops Bar Work Link"
- Create a screen with only one field: "Log Work". You can call it "Work Log in Transition".
- Add reflexive transition called "Log Work": in the statuses of our workflow where we want users to be allowed to log work, and we associate them screen "Work Log in Transition", created in previous step. These transitions have the same status as origin and destination, leaving the issue in the same status, but showing the user a screen where they will be able to log work.
Typically you will add this transition to "In Progress" status, but you can add this transition to all statuses easily using a global reflexive transition.
You can use conditions or validations to limit who can execute these transition, and thus who can log work.
User properties
We will use two user properties to store in order to implement this restriction. These two user properties are created and updated automatically, so we don't need to create them manually:
- Date of Last Work Log: contains the date of the last work log done by the user. The date is stored as a number of milliseconds since fixed date.
- Time Logged Last Day (minutes): contains the number of minutes logged by the user in the last day he has done any work logging.
Now we are ready to add validations and post-functions to transitions "Log Work", that will implement the restriction on the number of hours a user can log per day. In this particular example we will restrict the sum of hours a user can log in any issue to 12 per day:
Add Boolean Validator with math, date-time or text-string terms to transitions "Log Work" with the following configuration:
Boolean expression used is:
userProperty("Time Logged Last Day (minutes)", %{00020}) = "" OR toNumber(userProperty("Time Logged Last Day (minutes)", %{00020})) + {00141} <= 12 * 60 OR datePart({00057}, LOCAL) > toNumber(userProperty("Date of Last Work Log", %{00020})) AND {00141} <= 12 * 60
Note that:
- %{00020} is field code for virtual field "Current user"
- {00057} is code for numeric value of virtual field "Current date and time"
- {00141} is code for numeric value of virtual field "Work logged in transition (minutes)"
Once validation is added, transition "Log Work" will look like this:
We will add 4 post-functions to transitions "Log Work". Now we describe each of them by execution order:
Post-function 1: Set a field as a function of other fields
This post-function will store in "Ephemeral number 1" the value that should take user property "Time Logged Last Day (minutes)" after transition execution:
The 3 setting rules (one rule per line) used are:
[userProperty("Time Logged Last Day (minutes)", %{00020}) = "" OR userProperty("Date of Last Work Log", %{00020}) = ""]{00141}
[toNumber(userProperty("Date of Last Work Log", %{00020})) = datePart({00057}, LOCAL)]toNumber(userProperty("Time Logged Last Day (minutes)", %{00020})) + {00141}
[{00141} > 0]{00141}
Post-function 2: Set or create a user property
This post-function will set (or create in case it doesn't exist yet) user property "Time Logged Last Day (minutes)" with the value stored in "Ephemeral number 1":
Note that:
- %{00058} is field code for virtual field "Ephemeral number 1"
Post-function 3: Copy parsed text to a field
This post-function will store in "Ephemeral string 1" the value that should take user property "Date of Last Work Log" after transition execution:
Text to be parsed in advanced mode is:
{00141} > 0 ? datePart({00057}, LOCAL) : userProperty("Date of Last Work Log", %{00020})
Post-function 4: Set or create a user property
This post-function will set (or create in case it doesn't exist yet) user property "Date of Last Work Log" with the value stored in "Ephemeral string 1":
Note that:
- %{00061} is field code for virtual field "Ephemeral string 1"
Once all the post-functions have been inserted, transition "Log Work" will look like this:
Other examples of that functions
Boolean Validator with math, date-time or text-string terms
Set a field as a function of other fields
- Add watcher depending on security level
- Add watchers based on issue type
- Add watchers depending on the value of a custom field
- Assign issue based on the value of a Cascading Select custom field
- Assign issue to a specific user based on a specific custom field value
- Assign issue to current user if assignee is empty
- Assign issue to current user if the user is not member of a certain project role
- Change assignee based on a custom field
- Change parent's status depending on sub-task's summary
- Changing issue priority depending on issue description
- Compose dynamic text by inserting field values in a text template
- Copy "Due date" into a date type custom field in a linked issue if it's greater than current issue's "Due date"
- Limit the number of hours a user can log per day
- Make parent issue progress through its workflow
- Rise priority if due date is less than 3 weeks away
- Set "Due date" depending on the value of other fields, in case it's uninitialized
- Set "Due date" to a specific day of next week no matter of date of creation this week
- Set "Due date" to current date at issue creation if not initialized
- Set a custom field "Urgency" depending on a combined value of issue's priority and "Impact" custom field
- Set a date based on current date
- Set a field based on reporter's email
- Set a watcher at ticket creation depending on custom field's value
- Set assignee depending on issue type
- Set security level based on groups and project roles the reporter or creator are in
- Set security level depending on reporter or creator
- Set the assignee based on a condition
- Set the value of a field of type "User Picker" depending on other field's value
- Set watchers depending on the value of a custom field
- Setting a custom field (User Picker) based on the value of another custom field (Text Field)
- Setting a field's default value depending on another field
- Setting the priority depending on the multiplication of custom fields
- Transition an issue automatically depending on the value of a field
- Unassign an issue when assigned to project leader
- Update checkboxes custom field if a file has been attached during a transition
- Using project properties to calculate custom sequence numbers
- Add all assignees of certain sub-task types to a "Multi-User Picker" custom field
- Add and remove a single or a set of items from multi valued fields
- Add current user to comment
- Add or remove request participants
- Add watchers from a part of the issue summary: "Summary_text - watcher1, watcher2, watcher3, ..."
- Assign issue based on the value of a Cascading Select custom field
- Assign issue to last user who executed a certain transition in the workflow
- Automatically close resolved sub-tasks when parent issue is closed
- Automatically reopen parent issue when one of its sub-tasks is reopened
- Calculate the time elapsed between 2 transition executions
- Close parent issue when all sub-tasks are closed
- Combine the values of several Multi-User picker fields
- Compose a parsed text including the "full name" or a user selected in a User Picker custom field
- Compose dynamic text by inserting field values in a text template
- Copy issue labels to a custom field
- Copy the value of a user property into a user picker
- Create a comment in sub-tasks when parent transitions
- Execute transition in epic
- Getting the number of selected values in a custom field of type Multi Select
- Limit the number of hours a user can log per day
- Make a sub-task's status match parent issue's current status on creation
- Make parent issue progress through its workflow
- Moving story to "In Progress" when one of its sub-tasks is moved to "In Progress"
- Moving story to "Ready for QA" once all its sub-tasks are in "Ready for QA" status
- Parse Email adresses to watchers list
- Parsing text from last comment and appending it to issue's summary
- Remove versions selected in a version picker custom field
- Replace certain issue link types with different ones
- Restrict parent issue from closing if it has sub-tasks that were created during a given parent issue status
- Set a Select or Multi-Select field using regular expression to express the values to be assigned
- Set assignee depending on issue type
- Set field depending on time passed since issue creation
- Set priority for issues that have been in a certain status for longer than 24 hours
- Set security level based on groups and project roles the reporter or creator are in
- Transition linked issues in currently active sprint
- Transition only a sub-task among several ones
- Transition parent issue only when certain issue sub-task types are done
- Update Cascading Select custom field with a value of the field in parent issue
- Update checkboxes custom field if a file has been attached during a transition
- Validation on issue attachments
- Validation on MIME types of issue attachments
- Writing a comment to blocked issues when blocking issues are resolved
- Add all assignees of certain sub-task types to a "Multi-User Picker" custom field
- Add and remove a single or a set of items from multi valued fields
- Add current user to comment
- Add or remove request participants
- Add watchers from a part of the issue summary: "Summary_text - watcher1, watcher2, watcher3, ..."
- Assign issue based on the value of a Cascading Select custom field
- Assign issue to last user who executed a certain transition in the workflow
- Automatically close resolved sub-tasks when parent issue is closed
- Automatically reopen parent issue when one of its sub-tasks is reopened
- Calculate the time elapsed between 2 transition executions
- Close parent issue when all sub-tasks are closed
- Combine the values of several Multi-User picker fields
- Compose a parsed text including the "full name" or a user selected in a User Picker custom field
- Compose dynamic text by inserting field values in a text template
- Copy issue labels to a custom field
- Copy the value of a user property into a user picker
- Create a comment in sub-tasks when parent transitions
- Execute transition in epic
- Getting the number of selected values in a custom field of type Multi Select
- Limit the number of hours a user can log per day
- Make a sub-task's status match parent issue's current status on creation
- Make parent issue progress through its workflow
- Moving story to "In Progress" when one of its sub-tasks is moved to "In Progress"
- Moving story to "Ready for QA" once all its sub-tasks are in "Ready for QA" status
- Parse Email adresses to watchers list
- Parsing text from last comment and appending it to issue's summary
- Remove versions selected in a version picker custom field
- Replace certain issue link types with different ones
- Restrict parent issue from closing if it has sub-tasks that were created during a given parent issue status
- Set a Select or Multi-Select field using regular expression to express the values to be assigned
- Set assignee depending on issue type
- Set field depending on time passed since issue creation
- Set priority for issues that have been in a certain status for longer than 24 hours
- Set security level based on groups and project roles the reporter or creator are in
- Transition linked issues in currently active sprint
- Transition only a sub-task among several ones
- Transition parent issue only when certain issue sub-task types are done
- Update Cascading Select custom field with a value of the field in parent issue
- Update checkboxes custom field if a file has been attached during a transition
- Validation on issue attachments
- Validation on MIME types of issue attachments
- Writing a comment to blocked issues when blocking issues are resolved