Hi all,
I have two asset object fields, called Field A and Field B.
Let’s say I added the value “Jira” to Field A, and later changed it to “Confluence.” Now, I want to store the original value, "Jira," in Field B after it was changed to "Confluence." Could you please suggest a solution?
I am using Data Center v10.3.7, and we have ScriptRunner for Jira. I’m using the listener below, but I’m not getting the intended result.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import org.apache.log4j.Logger
def log = Logger.getLogger("com.example.plugins")
// IDs of the relevant Asset object fields
def sourceFieldId = "customfield_XXXXX"
def targetFieldId = "customfield_XXXXX"
def issue = event.issue
def cfManager = ComponentAccessor.customFieldManager
def sourceCF = cfManager.getCustomFieldObject(sourceFieldId)
def targetCF = cfManager.getCustomFieldObject(targetFieldId)
if (!sourceCF || !targetCF) {
log.warn("Source or target custom field not found.")
return
}
// Use field name for change detection
def sourceCFName = sourceCF.name
def changeItem = event.getChangeLog()?.getRelated("ChildChangeItem")?.find {
it.field == sourceCFName && it.oldstring != it.newstring
}
if (!changeItem) {
log.info("No change detected for Field A (${sourceCFName}). Skipping update.")
return
}
def mutableIssue = issue as com.atlassian.jira.issue.MutableIssue
def selected = mutableIssue.getCustomFieldValue(sourceCF)
if (!selected) {
log.info("No value selected in Field A.")
return
}
// Handle single-select field: get the object directly
def sourceObject = (selected instanceof Collection) ? selected[0] : selected
if (!sourceObject) {
log.warn("Source object is null after extraction.")
return
}
// Copy the Asset object to the target field
mutableIssue.setCustomFieldValue(targetCF, [sourceObject])
// Persist the issue update (user context is managed by ScriptRunner listener configuration)
ComponentAccessor.issueManager.updateIssue(
ComponentAccessor.jiraAuthenticationContext.loggedInUser,
mutableIssue,
EventDispatchOption.DO_NOT_DISPATCH,
false
)
if (sourceObject instanceof com.riadalabs.jira.plugins.insight.services.model.ObjectBean) {
log.info("Copied asset object '${sourceObject.name}' from Field A to Field B for issue ${issue.key}.")
} else {
log.warn("sourceObject is not an ObjectBean. Actual type: ${sourceObject?.getClass()?.name}")
}
Hi @Sriharsha
I have done multiple times a very similar stuff. Adding ObjectBeans to issues has always been working for me using the objectKey attribute of ObjectBean. This is also ensuring that there is no translation or such stuff, if you are working in a multi-language environment (not necessarily true for Asset objects, but still something to consider).
Therefore, I would change the setCustomFieldValue method accordingly:
mutableIssue.setCustomFieldValue(targetCF, [sourceObject.objectKey])
What you could also consider is to validate, if the sourceObject actually has the objectKey attribute and print it - at least for debugging purposes.
So my total change would look like this:
// Copy the Asset object to the target field
if(sourceObject?.objectKey){
log.info("Setting source object with key ${sourceObject.objectKey}")
mutableIssue.setCustomFieldValue(targetCF, [sourceObject.objectKey])
// Persist the issue update (user context is managed by ScriptRunner listener configuration)
ComponentAccessor.issueManager.updateIssue(
ComponentAccessor.jiraAuthenticationContext.loggedInUser,
mutableIssue,
EventDispatchOption.DO_NOT_DISPATCH,
false
)
log.info("Copied asset object '${sourceObject.name}' from Field A to Field B for issue ${issue.key}.")
}
else{
log.warn("sourceObject appears to be not an ObjectBean. Actual type: ${sourceObject?.getClass()?.name}")
}
Hope this helps!
Stefan
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Stefan Stadler - I'm getting an issue. Can you please provide me the full script?
Best regards,
Sriharsha
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Changed it like this -
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Sriharsha
getting the ObjectBean once more should not be necessary as the object from getCustomFieldValue is basically already a List of ObjectBean objects (which in your case only includes one member). Usually, it is the safest to assign the issue the objectKey of the desired object. That is why I am using the objectKey. The data needs to be passed in as an array independent from having an Asset custom field with single or multiple selection.
This is the complete code (untested as I do not have an Asset installation handy at the moment). I have also changed the ObjectBean.name into ObjectBean.label as name has been deprecated:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import org.apache.log4j.Logger
def myLog = Logger.getLogger("com.example.plugins")
// IDs of the relevant Asset object fields
def sourceFieldId = "customfield_XXXXX"
def targetFieldId = "customfield_XXXXX"
def issue = event.issue
def cfManager = ComponentAccessor.customFieldManager
def sourceCF = cfManager.getCustomFieldObject(sourceFieldId)
def targetCF = cfManager.getCustomFieldObject(targetFieldId)
if (!sourceCF || !targetCF) {
myLog.warn("Source or target custom field not found.")
return
}
// Use field name for change detection
def sourceCFName = sourceCF.name
def changeItem = event.getChangeLog()?.getRelated("ChildChangeItem")?.find {
it.field == sourceCFName && it.oldstring != it.newstring
}
if (!changeItem) {
myLog.info("No change detected for Field A (${sourceCFName}). Skipping update.")
return
}
def mutableIssue = issue as com.atlassian.jira.issue.MutableIssue
def selected = mutableIssue.getCustomFieldValue(sourceCF)
if (!selected) {
myLog.info("No value selected in Field A.")
return
}
// Check if selected is a collection (if multi-select) or a single object (single-select)
def sourceObject = (selected instanceof Collection) ? selected[0] : selected
// If sourceObject is an ObjectBean, it should have the objectKey
if (sourceObject instanceof com.riadalabs.jira.plugins.insight.services.model.ObjectBean) {
if (sourceObject?.objectKey) {
myLog.info("Setting source object with key ${sourceObject.objectKey}")
// Set the objectBean to the target field
mutableIssue.setCustomFieldValue(targetCF, [sourceObject.objectKey])
// Persist the issue update (user context is managed by ScriptRunner listener configuration)
ComponentAccessor.issueManager.updateIssue(
ComponentAccessor.jiraAuthenticationContext.loggedInUser,
mutableIssue,
EventDispatchOption.DO_NOT_DISPATCH,
false
)
myLog.info("Copied asset object '${sourceObject.label}' from Field A to Field B for issue ${issue.key}.")
} else {
myLog.warn("sourceObject does not have an objectKey: ${sourceObject?.label}")
}
} else {
myLog.warn("Selected value is not an ObjectBean. Actual type: ${selected?.getClass()?.name}")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Stefan Stadler , the field is bringing the main label attribute data which is a default text attribute.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Stefan Stadler , I have made some changes and the below script is working as expected --
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.