Hi all,
I'm trying to figure out if there is a way to use behaviors within scriptrunner to overwrite the "time" aspect of the Date Time Picker customfield?
Example: We setup a Date Time Picker customfield called Date Requested.
We want the user to be able to enter the date and time; but if they forget to enter the time or enter a time we don't want them to enter, we want to overwrite that time value aspect of that field with the current time.
Does this seem possible with scriptrunner?
Thanks,
Mike
Hello @Michael
You have two approaches to this requirement.
Bear the following in mind, where is the field changed because behaviors only work in the edit screens.
This can still be changed by inline edit.
1. Add a validation in the fields server side script and make the field mandatory.
Make the field mandatory
If you have an init function
getFieldByName('Date Requested').setRequired(true)
Validate the entered value
def requestedAtField = getFieldByName('Date Requested')
def requestedAt = requestedAtField.value
if ( requestedAt.before(earliestTime)
|| requestedAt.after(latestMernitedTime) ){
requestedAtField.setError('Please enter a valid date')
} else {
requestedAtField.clearError()
}
2. You can add a custom scripted post function in the create transition of the workflow
When can a person update this field? By this I mean only when it is created or while in a specific state, when the issue transitions from one state to another.
If you choose this route the field can be a scripted field so it only show up in the view screen if that makes sense to your use case.
In closing, the above are just examples to hopefully assist you in solving your problem. I have written here from memory so they probably do not work. You may be interested in the date format as well. This should get you started.
The user would be entering data within this field in the Create screen. So as several of you have suggested; this might be best as a post function.
The field would already be required by the field configuration - so we are already set there. I'd love to just input the current time instead of mandating a time range. (Easier for the user and us.
For example: If someone inputs "6/4/2023 12:00am" (12:00am being the default time) I'd like to change the 12:00am part to be the current time when the user creates the request.
So - if they created the request at 9:25am, the Date Requested field would change from 6/4/2023 12:00am to 6/4/2023 9:25am.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
There are functions in the date object for things like get year, get day etc.
You are interested in the get Time method.
Some things to consider:
People work late so what is the expected behavior if I create an issue at 18:35 in the evening and I do not populate the time.
I did select the date 2/6/2024
When this gets to the server the Date Time is 2/6/2024 18:35:46
There is a minute in the day where the unpopulated time and the time I created the issue is midnight. I think we can safely ignore this. It is unlikely and would just set the time to what the after hours rule is. None the less for both these scenarios we can just focus on when the issue was created.
The logic
1. Get the fields value
2. If the time portion of the value is 00:00:00.000 then
3. Get the current time
4. Extract the time portion of now.
5. Update the time part of the fields value with the time now
In a Post function
import org.joda.time.DateTime
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
def customFieldManager = ComponentAccessor.customFieldManager
final requestedDateFieldName = 'Date Requested'
def requestedDateField = customFieldManager.getCustomFieldObjectsByName(requestedDateFieldName)?.find{ it.name == requestedDateFieldName}
def requestedDate = issue.getCustomFieldValue(requestedDateFieldName) as DateTime
def isValidTime = false
// Chek if all time properties are 0
if (requestedDate) {
isValidTime = ( requestedDate.hourOfDay + requestedDate.minuteOfHour + requestedDate.secondOfMinute ) > 0
}
// The time was set, stop processing
if (isValidTime) return
def now = new Date()
final timeZoneId = ZoneId.systemDefault()
final dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
def wantedDateTimeAsText = "${requestedDate.toDate().toString()} ${now.hours}:${now.minutes}:${now.seconds}"
def wantedDateTime = LocalDateTime.parse(wantedDateTimeAsText, dateTimeFormatter).atZone(timeZoneId)
issue.setCustomFieldValue(requestedDateField, wantedDateTime)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi again @Graham Twine
Thanks for the details above.
I realize people work late, and that's why I'm flip flopping on how to input the time aspect for this customfield.
For your example above; the expected behavior is how you described it.
I'm not seeing the post function code you entered at the bottom of your reply; can you please re-post it?
Thanks,
Mike
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Michael ,
My bad I hit submit, when I was just about to draft that script.
The complete script is above.
The logic being, if the time was not entered into the field the hours minutes and seconds are integers and have the value 0 so we can look for hours + minutes + seconds > 0
if (requestedDate) {
isValidTime = ( requestedDate.hourOfDay + requestedDate.minuteOfHour + requestedDate.secondOfMinute ) > 0
}
If this is greater than 0 then the person creating the issue did input something here and we stop processing
// The time was set, stop processing
if (isValidTime) return
If hours + minutes + seconds is zero
// Get the time now
def now = new Date()
Get the timezone of the Jira server
final timeZoneId = ZoneId.systemDefault()
final dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
// Convert the requested Date Time field to a Date and convert the resulting object to a string.
// Get the hours, minutes and seconds from now and use all the se values to construct a new Date Time as a string
def wantedDateTimeAsText = "${requestedDate.toDate().toString()} ${now.hours}:${now.minutes}:${now.seconds}"
// Use the string to create a new DateTime Object
def wantedDateTime = LocalDateTime.parse(wantedDateTimeAsText, dateTimeFormatter).atZone(timeZoneId)
// Update the issue
issue.setCustomFieldValue(requestedDateField, wantedDateTime)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Michael
For your requirement, you will need to use ScriptRunner's Behaviour and configure a Server-Side Behaviour for the Date Requested field.
Below is a sample working code for your reference:-
def dateField = getFieldById(fieldChanged)
def dateFieldValue = dateFieldValue as Date
def beforeRange = new Date.plus(-30)
def dateAfter = new Date.plus(30)
dateField.clearFormError()
if(!dateFieldValue) { // The Date Field Must be filled
dateField.setFormError('Date Field Cannot Be Empty')
} else {
//Override the date rage to the current date and time
//if an incorrect date range is set.
if (dateFieldValue.after(dateAfter) || dateFieldValue.before(beforeRange)) {
dateField.setFormValue(new Date().toString())
}
}
Please note that the sample code above is not 100% exact to your environment. Hence you will need to make the required modifications.
I hope this helps to answer your question. :-)
Thank you and Kind regards,
Ram
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello again @Ram Kumar Aravindakshan _Adaptavist_
I'm not the best at reading code; but doesn't this set the entire date field to today's date?
We are looking for a script which leaves the date a user enters intact; and instead only changes the time aspect of this field to the current time.
For example: If someone inputs "6/4/2023 12:00am" (12:00am being the default time) I'd like to change the 12:00am part to be the current time when the user creates the request.
So - if they created the request at 9:25am, the Date Requested field would change from 6/4/2023 12:00am to 6/4/2023 9:25am.
I'm starting to think this might be better off as a post function custom script since this script would only be used for a specific workflow / issue type.
Hope the explanation above helps define what we are looking for.
~Mike
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Michael
In your last comment, you asked:-
I'm not the best at reading code; but doesn't this set the entire date field to today's date?
To answer your question, yes it does, i.e. depending on the value that has been set in the Date field. That is basically handled by:-
dateField.setFormValue(new Date().toString())
You also mentioned:-
We are looking for a script which leaves the date a user enters intact; and instead only changes the time aspect of this field to the current time.
For example: If someone inputs "6/4/2023 12:00am" (12:00am being the default time) I'd like to change the 12:00am part to be the current time when the user creates the request.
Ok for this, since you are also looking into time-specific modifications, I suggest looking at the example available in the Adaptavist Library.
I will update the example code in a bit.
Thank you and Kind regards,
Ram
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Michael scriptrunner would be able to do this. I'm not sure I'd put it in a behaviour, I think as a post function on the create issue would be a better place. Not sure what you mean by a date we don't want them too? How would you define that?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sometimes the users might either input a date, but forget to input a time (Leaving the time at the default) or they might input a time that is outside of business hours (For example, 3am or 8pm)
The only thing I'm trying to inspect / change would be the time aspect at the end.
IE: If someone inputs 6/4/2023 12:00am (12:00am being the default time) I'd like to change the 12:00am to be the current time.
So - if they enter the request at 9:25am, the Date Requested field would change from 6/4/2023 12:00am to 6/4/2023 9:25am.
Does that make sense?
~Mike
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.