Can I add story points to a custom field?

Kathleen Shafer May 5, 2015

I want to use t-shirt sizes instead of standard story points. Obviously I could create a custom field, but that would not map to reporting. Is there currently a way to resolve this?

7 answers

6 votes
Piotr Stefaniak July 27, 2017

Hello dear reader,


You might try to use our add-on for interactive estimations (via Planning Poker technique): Agile Poker Enterprise for JIRA. It allows you to do the estimating over T-shirt sizes (S, M, L, etc) and map the result to the numerical values (2, 3, 5, etc) while saving to the issue.


Disclaimer: I'm one of the developers behind that add-on, but nonetheless I thought that people looking here might be interested in knowing about that possibility. Feel free to ping me at support@spartez.com if you have any question.


Regards,
Piotr Stefaniak / Spartez Developer

1 vote
Steven F Behnke
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2015

I am planning doing this very same thing for our instance @Kathleen Shafer. I am planning on using T-Shirt sizes as well! My thoughts are like this:

  • I want to use the default Story Points field at the end of the day
    I do not want any strangeness with JIRA Agile
  • The estimation should be a single-select list with Small (1), Medium(2), Large(4), Extra Large(8)
  • I think here that it would be best to keep it simple. I don't want to code a whole bunch of logic, I just want to streamline the Story create process.

Edits and additions

Hello again @Kathleen Shafer! I have the post-function script working fine, and I think this is good enough for use. I am looking into the Scripted Field option still as well, this just isn't taking a priority. I hope you understand.

System Requirements

This post-function is only available to users of the Script Runner add-on, only available on JIRA Server. The Script Runner add-on lets us run Groovy scripts, for instance, as a post-function. We will leverage this to fulfil the software requirements.

Software Requirements

As a user, I should be able to set Story Points on issue creation using a select-list with T-Shirt estimation-sizing.

Set Up

  1. Get the Custom Field IDs of both the Story Points and T-Shirt Size custom fields
  2. Modify the below Groovy code with the Custom Field IDs that you just obtained
  3. Set field T-Shirt Size on your Create Screen
  4. Set field Story Points on your Edit and View Screens
  5. Add the Groovy code as an inline script, to be attached as a post-function of the Create transition

Use

  1. Open the Create Issue dialog
  2. Choose an option from T-Shirt Size
  3. Press Create
  4. Note the cooresponding value in the Story Points field
// Written by Steve Behnke, BlackPearl PDM
//
// The goal of this post-function is to simplify input of Story Points. Story Points normally, being a number field, allows people to enter any value
// However, without training or experience, these values vary wildly and may not be useful for reporting purposes until some time passes
//
// Using a 't-shirt size' select-list to populate the existing story points field let's us accomplish this in a flexible manner that really doesn't change the actual behavior of the story points field at all. We're just pre-populating it. 
//
// This is as opposed to a scripted field of sorts, which could 'map' the values directly with no room for flexibility.
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.util.IssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
 
// set up logging
log.setLevel(org.apache.log4j.Level.INFO)

log.info "Executing T-Shirt size > Story Points conversion!"
// gets a reference to the IssueManager and CustomFieldManager manager classes

IssueManager issueManager = ComponentManager.getInstance().getIssueManager();
CustomFieldManager customFieldManager = ComponentManager.getInstance().getCustomFieldManager();

// gets a reference to the custom field objects
// note, that since I reference the fields by internal ID these will need to be modified to work correctly
CustomField tshirtsizeField = customFieldManager.getCustomFieldObject( "customfield_12214" );
CustomField storypointsField = customFieldManager.getCustomFieldObject( "customfield_10004" );

log.debug "get tshirt value"
Object tshirtValue = issue.getCustomFieldValue(tshirtsizeField);
// introduce the changeHolder element, in order to update fields
IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
 
// create values as doubles, appropriate for "JIRA Number Fields;" Story Points is this type of field
//
// T-Shirt size = Small
Double pSmall = 1
//
// T-Shirt size = Medium
Double pMedium = 4
//
// T-Shirt size = Large
Double pLarge = 9
//
// T-Shirt size = X-Large
Double pXLarge = 16
 
// retrieves the custom field value object from the issue and sets the story point value
if(tshirtValue.toString() == "Small") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pSmall), changeHolder);
	log.debug "size = Small, value =" + pSmall.toString()
} 
else if(tshirtValue.toString() == "Medium") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pMedium), changeHolder);
	log.debug "size = Medium, value =" + pMedium.toString()
}
else if(tshirtValue.toString() == "Large") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pLarge), changeHolder);
	log.debug "size = Large, value =" + pLarge.toString()
} 
else if(tshirtValue.toString() == "X-Large") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pXLarge), changeHolder);
	log.debug "size = X-Large, value =" + pXLarge.toString()
} 
else {
// do nothing
log.debug "Size was set to null; not setting story points."
};
Kathleen Shafer May 5, 2015

Ahh...very cool. I think that would work! Would you mind sharing your script when you are finished?

Steven F Behnke
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2015

Totally would. Let me think about my requirements a bit more. I will save this and get back to you. :)

Steven F Behnke
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 7, 2015

@Kathleen Shafer, @Kathleen Shafer, just bumping so you see! smile

0 votes
Michael Benz May 9, 2017

Interesting approach - might use the exact same script to transfer the T-Shirt sizes in a new custom field to story points. I changed the script slightly and used the event variable using it as a custom script listener in "Script Runner - Script Listeners" for the following Events:

  • Issue Created
  • Issue Updated
// Written by Steve Behnke, BlackPearl PDM, modified by MBe
// Source: https://community.atlassian.com/t5/JIRA-questions/Can-I-add-story-points-to-a-custom-field/qaq-p/25143
//
// The goal of this post-function is to simplify input of Story Points. Story Points normally, being a number field, allows people to enter any value
// However, without training or experience, these values vary wildly and may not be useful for reporting purposes until some time passes
//
// Using a 'T-Shirt size' select-list to populate the existing story points field let's us accomplish this in a flexible manner that really doesn't change the actual behavior of the story points field at all. We're just pre-populating it. 
//
// This is as opposed to a scripted field of sorts, which could 'map' the values directly with no room for flexibility.
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.util.IssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
 
// set up logging
log.setLevel(org.apache.log4j.Level.INFO)

log.info "Executing T-Shirt size > Story Points conversion!"

// gets a reference to the custom field objects
// note, that since I reference the fields by internal ID these will need to be modified to work correctly
CustomField tshirtsizeField =  ComponentAccessor.getCustomFieldManager().getCustomFieldObject(10101L);
CustomField storypointsField = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(10102L);

log.debug "get T-Shirt value"
// from an event we first need to get the issue
Issue issue = event.getIssue();
Object tshirtValue = issue.getCustomFieldValue(tshirtsizeField);
// introduce the changeHolder element, in order to update fields
IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
 
// create values as doubles, appropriate for "JIRA Number Fields;" Story Points is this type of field
//
// T-Shirt size = X-Small
Double pXSmall = 1

// T-Shirt size = Small
Double pSmall = 3
//
// T-Shirt size = Medium
Double pMedium = 5
//
// T-Shirt size = Large
Double pLarge = 8
//
// T-Shirt size = X-Large
Double pXLarge = 13
//
// T-Shirt size = XX-Large
Double pXXLarge = 20
 
// retrieves the custom field value object from the issue and sets the story point value
if(tshirtValue.toString() == "👕 XS") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pXSmall), changeHolder);
	log.debug "size = X-Small, value =" + pXSmall.toString()
} 
else if(tshirtValue.toString() == "👕 S") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pSmall), changeHolder);
	log.debug "size = Small, value =" + pSmall.toString()
} 
else if(tshirtValue.toString() == "👕 M") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pMedium), changeHolder);
	log.debug "size = Medium, value =" + pMedium.toString()
}
else if(tshirtValue.toString() == "👕 L") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pLarge), changeHolder);
	log.debug "size = Large, value =" + pLarge.toString()
} 
else if(tshirtValue.toString() == "👕 XL") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pXLarge), changeHolder);
	log.debug "size = X-Large, value =" + pXLarge.toString()
} 
else if(tshirtValue.toString() == "👕 XXL") {
	storypointsField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(storypointsField), pXXLarge), changeHolder);
	log.debug "size = XX-Large, value =" + pXXLarge.toString()
} 
else {
	// do nothing - just log the provided value for debugging
	log.debug "Size was set to null; not setting story points. provided value was: " + tshirtValue.toString()
};
Michael Benz May 22, 2017

Changed Story-Points were not updated on the Backlog correctly. Had to reindex the issue using the issueIndexingService.reIndex(issueManager.getIssueObject(issue.id)); call to fix that behavior.

0 votes
Kathleen Shafer May 7, 2015

I am on JIRA server. Yes interesting point on the reporting. So basically on the backend the sizes would map to a number (XS=1, S=2 and so on) so the reporting would pull from numbers. The reporting would still be viewed with numbers, since you couldn't really translate the numbers back into sizes (or maybe someone would like to see that).

0 votes
Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2015

Yes, it is, somehow. use the standard story points CF & JJUPIN + JJUPIN Agile; on the view screens, you can call a LiveFields lfSet replacing the number with S,M,L,XL, XXL, etc.

However, on the edit screens, I doubt it will work. That value needs to be posted, and it has to be numeric. If you do not mind editing numbers but seeing it as you want, you have this (partial) solution.

0 votes
Steven F Behnke
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2015

Kathleen, are you on JIRA Cloud or JIRA server? If you are on JIRA cloud scriptrunner isn't an option.

0 votes
Nicolas Bourdages
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2015

This is fun and unusual. Since Story points are meant to add up in reporting, like in a Velocity chart, how would that help to put anything but numbers in there? What report exactly would make sense with t-shirt sized instead of numbers? If you explain further what you need to figure out with the reports, we might be able to suggest something.

Suggest an answer

Log in or Sign up to answer