Managing Inventories on asset custom field value change - Getting amount from screen - Example 3

It is possible to track quantity of an asset while it is added to the issue custom field or removed from it. Amount of the inventory will be taken from another field on the screen. Please follow the steps of the following example.

In this example, we'll define a global transition with a custom screen (Update Asset) to increase or decrease quantity value of an asset when it is added or removed from asset custom field. Asset won't be updated when asset won't added to the issue or removed from it.

Define a Quantity attribute

Add it to the desired form

Create multiple assets and set Quantity values (i.e 50, 40, 30)

Define a Text Custom Field to set amount of inventories

Name: Quantities of Assets
Description: "Asset Id:Quantity" pairs to change Asset's actual quantity, example: 2001:5, 2002:2

Define a screen to Update Asset

Add "Assets" and "Quantities of Assets" fields to the new screen. Remove asset custom field from edit and create screens. Only this screen will update assets on transition. View Issue screen will have Asset custom field as read-only.

Define a new transition with Update Asset screen

In this example it is defined as All-to-self. You can define for a specific status as well. 

Define the post function to update quantity for the Update Asset transition

Select Add "[AIP] - Update Asset workflow post function" to the workflows to update an asset object on transition. And select Quantity field. Leave form parameter as blank to set any matching form.

Post function Groovy Script

import inventoryplugin.entity.JipInventoryItem;
import org.apache.commons.lang3.StringUtils;
import com.atlassian.jira.issue.Issue;

// "Quantities of Assets" text custom field let us set amount of the inventories in the transition
// customfield_10501 is the id of the custom field.
// We expect a pattern "Asset Id:Quantity" pairs, example: 2001:5, 2002:2
String getTextCustomFieldValue(Issue issueParam) {
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def cField = customFieldManager.getCustomFieldObject("customfield_10501")
    return issueParam.getCustomFieldValue(cField)

// if asset not found or an exception occurres, "0" will return
Integer getAmountOfAssetInThisTransition(Issue issueParam) {
    try {
        Integer result = 0;
        def quantityFieldOfIssue = getTextCustomFieldValue(issueParam);
        if (quantityFieldOfIssue != null) {
            def assetPairs = quantityFieldOfIssue.split(',');
            assetPairs.each { assetPair ->
                try {
                    def (assetId, assetQuantity) = assetPair.trim().split(":");
                    if (assetId.toString() == asset.ID.toString()) result = assetQuantity.trim() as Integer;
                catch (Exception e) {
                    // do nothing

        return result;
    catch (Exception e) {
        return 0

// as field is a Text type we need to convert value to int and return as String
String getNewQuantityValueOfAsset() {
    def stringValue = StringUtils.trim(aipUtils.getAttributeValueAsStringByName(asset, 'Quantity'));

    if (stringValue != null && stringValue.isInteger()) {

        Integer prevAmount = getAmountOfAssetInThisTransition(originalIssue);
        Integer newAmount = getAmountOfAssetInThisTransition(issue);
        if (prevAmount == null) prevAmount = 0;
        if (newAmount == null) newAmount = 0;

        int intValue = stringValue as Integer
        if (assetStatus == 'added') {
            intValue = intValue - newAmount;
        } else if (assetStatus == 'removed') {
            intValue = intValue + prevAmount;
        } else if (assetStatus == 'noChange') {
            // asset was already in the field. We'll try to calculate the amount of the change.
            if (prevAmount != newAmount) {
                intValue = intValue - (newAmount - prevAmount);

        return intValue as String
    } else {
        return stringValue
return getNewQuantityValueOfAsset();

  • aipUtils.getAttributeValueAsStringByName returns the Quantity attribute value of the asset.  Quantity will calculated as 0 if nothing found for asset in "Quantities of Assets" field
  • "return null" result won't update asset. If you want to clear attribute value return empty String "return ''"
  • This script will be executed for each assets of all custom fields that matches the configuration. Assets also includes removed assets to let you control inventory. If you want to do nothing for assets removed from issue you can use if (assetStatus == 'removed') return null
  • Don't forget to change custom field id. In this example it is customfield_10501

Test it on Post Function Create Screen and publish workflow

Update asset "Quantities of Assets" field for test


Publish workflow and now ready to try it with test issues and test assets.

Update assets with Update Asset transition

First: Issue has no assets 

3 Phones have 50, 40, 30 Quantity values

Delete "Quantities of Assets" value with Update Asset transition before test.

Update issue Issue updated with transition

Assets: MP-001 #2102 [Phone] , MP-002 #2101 [Phone]
Quantities of Assets: 2102:4, 2101:3

Issue updated and 2 phones are updated with 46 and 37 quantity values (before 50 and 40)

Now 3rd asset is added

Quantity values after update is 46, 37, 25

Now 2 assets are removed

Quantity values after update is 46, 40, 30

Now change inventory amount from 4 to 7

Quantity values after update is 43, 40, 30

Now remove last asset from issue

Quantity values after update is 50, 40, 30 - as we started at the beginning.