├── .gitignore ├── README.md ├── pom.xml └── src └── main ├── confluence ├── UpdateGroupUsingCertainUsers.groovy ├── console │ ├── CleanGroupPermissions.groovy │ ├── CleanPageVersions.groovy │ └── RemoveMailFromUsernames.groovy ├── scheduled_jobs │ ├── DbReportForMySql.groovy │ └── DbReportWithSrResources.groovy ├── СqlLabelAttachments.groovy ├── СqlLabelAttachments1.groovy └── СqlLabelPages.groovy ├── jira ├── JiraUtilHelper.groovy ├── REST_endpoints │ ├── DataFromDBForSelectListConversion.groovy │ ├── GetBitBucketProjectNamesToSelectList.groovy │ └── reports_with_gui │ │ ├── DateReport.groovy │ │ └── DateReportGui.groovy ├── ReportGenerator.groovy ├── behaviours │ ├── HideSelectListOptionsBaseOnReporterGroups.groovy │ ├── SetDescriptionBasedOnSelectListVal.groovy │ ├── SetReporter.groovy │ ├── epic_lock │ │ ├── ClearErrorOnEpicLinkFieldDuringIssueTypeChange.groovy │ │ ├── DisableEditingBasedOnFieldVal.groovy │ │ ├── HideLockIndicatorField.groovy │ │ ├── LimitLinkingToEpicFromChildBasedOnEpicFieldVal.groovy │ │ └── readme.md5 │ └── insight │ │ ├── SetUserGroupPicker.groovy │ │ ├── SetUserPickerAndDescription.groovy │ │ └── SetUserPickerBasedOnGroupPickerAndIql.groovy ├── conditions │ ├── CheckBlockerStatus.groovy │ ├── DisableForHighPriorityAndCertainCfVal.groovy │ ├── DisableForLowPriority.groovy │ ├── FieldValuesAsString.groovy │ ├── StatusLimitationBasedOnHistory.groovy │ ├── SubTaskStateCondition.groovy │ ├── UserGroups.groovy │ └── UserRoles.groovy ├── escalation_services │ ├── AddLabel.groovy │ └── ClearFieldVal.groovy ├── fragments │ └── HideUiElementsBasedOnFieldValue.groovy ├── jobs │ ├── DbReport.groovy │ ├── RemoveEpicsAndIssuesInEpicFromTheBroard.groovy │ └── weeklyJQLReport.groovy ├── listeners │ ├── AddFixVersionBasedOnLinkedIssue.groovy │ ├── AppendTextFromCfToCf.groovy │ ├── CheckAssigneeBasedOnHistory.groovy │ ├── CopyCascadeDownSLFieldfromParentToAllChilds.groovy │ ├── CopySLCFDuringIssueSplit.groovy │ ├── CopyValueFromParentOrToChildAndChildChild.groovy │ ├── RemoteIssueCreationWithAttacment.groovy │ ├── RemoveFixVersionBasedOnLinkedIssue.groovy │ ├── SendReportAboutSprint.groovy │ ├── SetCFValueBasedOnSprint.groovy │ ├── SetCFValueByReporter.groovy │ ├── SetCFValueToNextQuater.groovy │ ├── SetCFValuesBasedOnDueDate.groovy │ ├── SetSelectListFieldBasedOnAssignee.groovy │ ├── SwapIssueLinks.groovy │ ├── UpdateCFbasedOnLabel.groovy │ ├── UpdateIssueDateByVersion.groovy │ ├── UpdateLableInLinkedIssues.groovy │ ├── UpdateOfLinkedIssuesCFBasedOnParentHistory.groovy │ ├── copy │ │ ├── CommentAttachmentToLinkedInwardIssues.groovy │ │ ├── CommentAttachmentToLinkedOutwardIssues.groovy │ │ └── SelectListValFromEpicToIssuesInEpic.groovy │ ├── set_field_based_on │ │ ├── LinkedIssuesWithCondition.groovy │ │ ├── PriorityChange.groovy │ │ ├── SprintDates.groovy │ │ └── StatusCategory.groovy │ └── sync │ │ ├── AffectsVersionsCopyWithinCommonProject.groovy │ │ ├── AffectsVersionsSyncWithinCommonProject.groovy │ │ └── VersionsFromMultipleProjectToSingleProject.groovy ├── post_functions │ ├── AddRemoteLinkFromCFtoIssue.groovy │ ├── AllSubTasksAreClosed.groovy │ ├── AssignBasedOnHistoryStatus.groovy │ ├── ChangeIssueTypeBasedOnFieldValues.groovy │ ├── CheckIssueWithSameSummaryAndLinkIt.groovy │ ├── CopyFieldsToCertainIssueInEpicAndTransitIt.groovy │ ├── CopyIssueLinksFromSubTaskToParentScreen.groovy │ ├── CopySelectListCFValueWithinTheSameIssue.groovy │ ├── CopySelectListCfValueFromParentToSubtask.groovy │ ├── EstimateIssues.groovy │ ├── FindIssuesTransitUpdateCF.groovy │ ├── GroupPickerCfUpdate.groovy │ ├── JenkinsTriggerJob.groovy │ ├── MLCScopyFieldDuringCreationFromParentToSubTask.groovy │ ├── MLCScopyFieldFromSubTaskToParent.groovy │ ├── MyCloneIssue.groovy │ ├── SetPriority.groovy │ ├── StoryCreationForEpic.groovy │ ├── UpdateFieldBasedOnHistory.groovy │ ├── UpdateSecurityLevel.groovy │ ├── UpdateSelectListCF.groovy │ ├── UpdateUserPickerCF.groovy │ ├── bamboo │ │ └── RunBambooBuild.groovy │ ├── bitbucket │ │ └── CreateProjectOrRepoBitBucket.groovy │ ├── create_issue │ │ ├── CreateIssueWithLastComment.groovy │ │ ├── CreateLinkedIssue.groovy │ │ ├── CreateLinkedIssueWithTeamCityRequest.groovy │ │ └── RemoteIssueWithLinkCreation.groovy │ ├── insight │ │ ├── ParseMailAbdUpdateInsightFields.groovy │ │ ├── SetInsightObjectFieldBasedOnReporterRetrievedViaIQL.groovy │ │ ├── SetOrganisationBasedOnReporterInsightValue.groovy │ │ └── legacy_SetInsightObjectFieldBasedOnReporterRetrievedViaIQL.groovy │ ├── set_field_based_on │ │ ├── DateFieldValues.groovy │ │ └── ResolutionDate.groovy │ ├── sub_task_creation_based_on │ │ ├── SingleSelectListValue0.groovy │ │ └── SingleSelectListValue1.groovy │ ├── transitions │ │ ├── ChangeEpicStatusDone.groovy │ │ ├── ChangeEpicStatusInProgress.groovy │ │ ├── ChangeFeatureStatusDone.groovy │ │ ├── ChangeFeatureStatusInProgress.groovy │ │ ├── FastTrackTransitionAnIssueConfition.groovy │ │ ├── TransitAllIssueTreeToStopedIfChildStoped.groovy │ │ ├── TransitAllIssuesIfAllClosed.groovy │ │ ├── TransitCascadeParentsWhenFirstChildReopen.groovy │ │ ├── TransitCascadeParentsWhenFirstSubtaskInprogress.groovy │ │ ├── TransitEpicBasedOnStoryStatus.groovy │ │ ├── TransitEpicBasedOnStorySubTasks.groovy │ │ ├── TransitIssueBasedOnFieldValues.groovy │ │ ├── TransitIssueIfAnotherTransitionDone.groovy │ │ ├── TransitLinkedIssues.groovy │ │ ├── TransitParentIssueOfSubtaskInProgress.groovy │ │ ├── TransitParentIssueOfSubtaskToDone.groovy │ │ ├── TransitParentIssueWhenSubTaskIsInprogress.groovy │ │ ├── TransitParentToDoneBasedOnStatusofChild.groovy │ │ ├── TransitParentToInProgressByFirstChildInProgress.groovy │ │ ├── TransitPortfolioParentIfChildInStatus.groovy │ │ ├── TransitSubTaskFromSubTask.groovy │ │ ├── TransitSubtaskDependingOnOtherSubtaks.groovy │ │ └── TransitToCompleteWhenAllChildsCompleted.groovy │ └── watchers │ │ ├── AddWatchersBasedOnCustomFieldValue.groovy │ │ └── HardcodedListOfWatchers.groovy ├── script_console │ ├── AddToProjectRole.groovy │ ├── AttachmentLinks.groovy │ ├── ChangeBoardFilter.groovy │ ├── ChangeReporterAssigneeFromFile.groovy │ ├── CleanGroupRoles.groovy │ ├── DeactivateUsers.groovy │ ├── FieldAppender.groovy │ ├── MakeEpicFieldRequired.groovy │ ├── MergePortfolioChildIssueToOneFeature.groovy │ ├── PermissionSchemeBulkAssignment.groovy │ ├── RenameActiveWorkflow.groovy │ ├── RenameUsernamesToEmailPrefix.groovy │ ├── RenameUsers.groovy │ ├── SetFieldValBasedOnSprintDatesUsingJql.groovy │ ├── UpdateEndDateCFBasedOnHistory.groovy │ ├── UpdateIssueSystemFields.groovy │ ├── UpdateStartDateCFBasedOnHistory.groovy │ ├── UpdateTimeToSLAFields.groovy │ ├── UpdatesOfCFbyUser.groovy │ ├── UsersRemovalFromProjectRole.groovy │ ├── VersionSynchroniser.groovy │ ├── bulk_issue_creation │ │ ├── EpicsWithIssues.groovy │ │ ├── EpicsWithoutIssues.groovy │ │ └── ProjectsWithIssues.groovy │ ├── cleanup │ │ ├── DeleteInactiveIssueTypeSchemes.groovy │ │ ├── DeleteInactiveIssueTypeScreenSchemes.groovy │ │ ├── DeleteInactiveScreenSchemes.groovy │ │ ├── DeleteInactiveScreens.groovy │ │ ├── DeleteInactiveWorkflowSchemes.groovy │ │ └── DeleteInactiveWorkflows.groovy │ └── reports │ │ ├── CustomFieldReport.groovy │ │ ├── IssueTypeReport.groovy │ │ └── WorkflowStatusReport.groovy ├── scripted_fields │ ├── CalculateCFsValues.groovy │ ├── CalculateCFsValuestp.groovy │ ├── CookieRestCallScriptedFieldForSignaturePluginHTML.groovy │ ├── CookieRestCallScriptedFieldForSignaturePluginWikiMarkup.groovy │ ├── CustomPriority.groovy │ ├── FinishedEpicsUnderFeature.groovy │ ├── FixVersionOrStatusChangeWithinCurrentDate.groovy │ ├── LastAttachmentDate.groovy │ ├── LastComment.groovy │ ├── MaxValOfDateFieldInEpicIssues.groovy │ ├── MinValOfDateFieldInEpicIssues.groovy │ ├── NotFinishedEpicsUnderFeature.groovy │ ├── OrigEstMinusRemEst.groovy │ ├── ParentIssueKeyForEpic.groovy │ ├── ParentSubtaskFilter.groovy │ ├── PlannedStoryPointsinChildren.groovy │ ├── SumOfChildStoryPointsOnFeature.groovy │ ├── SumOfDateFieldInEpicIssues.groovy │ ├── SumOrigEstInEpicIssues.groovy │ ├── SunLoggedWorkInEpicsIssuesAndSubTask.groovy │ ├── counters │ │ ├── GroupPickerChanges.groovy │ │ ├── ReopenCounter.groovy │ │ └── StatusChanges.groovy │ └── xray │ │ ├── XrayFixVersionTraceabilityInformation.groovy │ │ └── XrayTestRunStatusInCurrentVersion.groovy ├── startup │ └── MakeEpicFieldRequiredInCertainFieldConfigurations.groovy └── validators │ ├── CheckSubtaskStatusWithCertainSummary.groovy │ ├── CommentRequiredDuringTransition.groovy │ ├── GroupChecker.groovy │ ├── IssueLinkValidationWithScreen.groovy │ ├── LinkedIssueFromCertainProjectInClosedStatus.groovy │ ├── SlAndTextareaValuesMulitiValidation.groovy │ ├── TableGridFieldRequired.groovy │ ├── TableGridFieldRequiredTransition.groovy │ └── transition_screens │ ├── AssigneeInCertainGroupRelatedToGroupPickerCF.groovy │ ├── ValidateAnyCustomFieldOnTheScreen.groovy │ └── fixVersionsValidation.groovy └── jira_cloud ├── listeners ├── CheckDueDateAndLeaveComment.groovy ├── FieldSplitter.groovy ├── SetParentIssueFieldBaseOnSubTasksDueDates.groovy ├── SumStoryPointsOfSubTasks.groovy └── set_field_value_based_on │ ├── AssigneeGroups.groovy │ ├── AssignmentDate.groovy │ ├── IssueLinkAndSubTaskDueDate.groovy │ ├── LabelsReporterGroups.groovy │ ├── LabelsReporterGroupsFieldValue.groovy │ ├── LastComment.groovy │ ├── SlaBreachDate.groovy │ ├── SlaBreachDateCR.groovy │ ├── SlaBreachDateLaw.groovy │ ├── SprintHistoryResolutionDate.groovy │ ├── Votes.groovy │ └── hierarchy │ ├── AdvancedRoadmapsCalculation_00.groovy │ ├── AdvancedRoadmapsCalculation_01.groovy │ ├── OriginalEstimateForSubTaskTaskEpic.groovy │ └── SubTaskTaskEpicCalculation_00.groovy ├── post_functions ├── SetFieldsValues.groovy ├── SetSprint.groovy ├── gitlab │ └── CreateBranchOnBehalfOfReporter.groovy └── set_field_value_based_on │ ├── MultipleValuesFromOtherFields.groovy │ ├── RegExpDescription.groovy │ └── ReporterGroups.groovy ├── scheduled_jobs ├── JqlSearchWithFieldUpdate.groovy └── JqlSearchWithIssueCreation.groovy ├── script_console ├── UpdateCFSelectListBasedOnReportersGroup.groovy └── bulk_issue_creation │ ├── epicsWithIssues.groovy │ └── epicsWithoutIssues.groovy └── templates ├── GitLab.groovy └── Jira.groovy /.gitignore: -------------------------------------------------------------------------------- 1 | # Intellij 2 | .idea/ 3 | *.iml 4 | *.iws 5 | 6 | # Mac 7 | .DS_Store 8 | 9 | target/ 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | https://developer.atlassian.com/server/jira/platform/performing-issue-operations/ - IssueService vs issueManager 2 | 3 | 4 | Script Runner Repository 5 | ======================== 6 | 7 | This project is a basic template that can be used to store all custom scripts created for ScriptRunner. 8 | 9 | It provides some dependencies and one very simple example that is mentioned in the [documentation](https://scriptrunner.adaptavist.com/latest/DevEnvironment.html). -------------------------------------------------------------------------------- /src/main/confluence/UpdateGroupUsingCertainUsers.groovy: -------------------------------------------------------------------------------- 1 | package confluence 2 | 3 | import com.atlassian.confluence.user.UserAccessor 4 | import com.atlassian.spring.container.ContainerManager 5 | 6 | def userAccessor = ContainerManager.getInstance().getComponent("userAccessor") as UserAccessor 7 | def allUserNames = userAccessor.userNamesWithConfluenceAccess 8 | def group = userAccessor.getGroup("internal-users") 9 | allUserNames.each { userName -> 10 | def user = userAccessor.getUserByName(userName) 11 | if (user.email.contains("@example.com")) { 12 | userAccessor.addMembership(group, user) 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/confluence/console/CleanGroupPermissions.groovy: -------------------------------------------------------------------------------- 1 | package confluence.console 2 | 3 | import com.atlassian.confluence.internal.security.SpacePermissionContext 4 | import com.atlassian.confluence.internal.security.SpacePermissionManagerInternal 5 | import com.atlassian.confluence.security.SpacePermission 6 | import com.atlassian.confluence.spaces.Space 7 | import com.atlassian.spring.container.ContainerManager 8 | import com.atlassian.confluence.spaces.SpaceManager 9 | 10 | def manager = ContainerManager.instance.getComponent("spacePermissionManager") as SpacePermissionManagerInternal 11 | SpaceManager sm = (SpaceManager) ContainerManager.getInstance().getComponent("spaceManager") 12 | 13 | List all = sm.getAllSpaces() 14 | Set groups = new HashSet<>() 15 | groups.add("confluence-administrators") 16 | groups.add("confluence-users") 17 | 18 | for (Space space : all) { 19 | List spacePermissionsToRemove = new ArrayList<>(space.getPermissions()) 20 | for (SpacePermission spacePermission : spacePermissionsToRemove) { 21 | if (spacePermission.isGroupPermission() && groups.contains(spacePermission.getGroup())) 22 | manager.removePermission(spacePermission, SpacePermissionContext.createDefault()) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/confluence/console/CleanPageVersions.groovy: -------------------------------------------------------------------------------- 1 | package confluence.console 2 | 3 | import com.atlassian.confluence.pages.Page 4 | import com.atlassian.confluence.pages.PageManager 5 | import com.atlassian.confluence.spaces.SpaceManager 6 | import com.atlassian.spring.container.ContainerManager 7 | 8 | def pageManager = (PageManager) ContainerManager.getInstance().getComponent("pageManager") 9 | def spaceManager = (SpaceManager) ContainerManager.getInstance().getComponent("spaceManager") 10 | 11 | def space = spaceManager.getSpace("SPACEKEY") 12 | def pages = pageManager.getPages(space, true) //boolean currentOnly 13 | 14 | def versionsToLeave = 0 15 | def removedPagesTitles = [] 16 | 17 | pages.each { 18 | int previousVersion = it.getPreviousVersion() 19 | if (previousVersion > versionsToLeave) { 20 | for (int i = 1; i <= (previousVersion - versionsToLeave); i++) { 21 | try { 22 | def pageForRemoval = (Page) pageManager.getPageByVersion(it, i) 23 | removedPagesTitles << "title: " + pageForRemoval.displayTitle + " - version: " + pageForRemoval.version 24 | pageForRemoval.remove(pageManager) 25 | } catch (NullPointerException e) { 26 | log.error(e.message) 27 | } 28 | } 29 | } 30 | } 31 | removedPagesTitles.size() -------------------------------------------------------------------------------- /src/main/confluence/console/RemoveMailFromUsernames.groovy: -------------------------------------------------------------------------------- 1 | package confluence.console 2 | 3 | import com.atlassian.user.UserManager 4 | import com.atlassian.sal.api.component.ComponentLocator 5 | import com.atlassian.confluence.user.UserAccessor 6 | import com.atlassian.user.search.page.Pager 7 | 8 | def userManager = ComponentLocator.getComponent(UserManager) 9 | def userAccessor = ComponentLocator.getComponent(UserAccessor) 10 | 11 | def userNames = userManager.userNames as Pager 12 | def affectedUserNames = userNames.findAll { String userName -> 13 | userName.contains("@") 14 | } as List 15 | 16 | affectedUserNames.each { String userName -> 17 | log.warn "Old username = ${userName}" 18 | def newUserName = userName.substring(0, userName.indexOf("@")) 19 | log.warn "New username = ${newUserName}" 20 | userAccessor.renameUser(userAccessor.getUserByName(userName), newUserName) 21 | } -------------------------------------------------------------------------------- /src/main/confluence/СqlLabelAttachments.groovy: -------------------------------------------------------------------------------- 1 | package confluence 2 | 3 | import com.atlassian.confluence.api.model.pagination.PageResponse 4 | import com.atlassian.confluence.api.model.pagination.SimplePageRequest 5 | import com.atlassian.confluence.api.service.search.CQLSearchService 6 | import com.atlassian.confluence.labels.Label 7 | import com.atlassian.confluence.labels.LabelManager 8 | import com.atlassian.confluence.pages.AttachmentManager 9 | import com.atlassian.plugin.osgi.container.OsgiContainerManager 10 | import com.atlassian.spring.container.ContainerManager 11 | import com.atlassian.confluence.api.model.content.Content 12 | 13 | final String CQL_QUERY = 'type = attachment and lastModified > "2020/05/15"' 14 | final String LABEL_VALUE = "content_attachments" 15 | final int MAX_ENTITIES = 500 16 | 17 | def osgiContainerManager = ContainerManager.getComponent("osgiContainerManager") as OsgiContainerManager 18 | def cqlSearchService = osgiContainerManager.getServiceTracker(CQLSearchService.class.name).service as CQLSearchService 19 | 20 | def numberOfResultsFound = cqlSearchService.countContent(CQL_QUERY) 21 | def finalResult = new ArrayList(numberOfResultsFound) 22 | def pageRequest = new SimplePageRequest(0, MAX_ENTITIES) 23 | def searchResult = cqlSearchService.searchContent(CQL_QUERY, pageRequest) as PageResponse 24 | finalResult.addAll(searchResult.results) 25 | 26 | while (searchResult.hasMore()) { 27 | def nextPageRequest = new SimplePageRequest(finalResult.size(), MAX_ENTITIES) 28 | searchResult = cqlSearchService.searchContent(CQL_QUERY, nextPageRequest) 29 | finalResult.addAll(searchResult.results) 30 | } 31 | 32 | def labelManager = ContainerManager.getComponent("labelManager") as LabelManager 33 | def attachmentManager = ContainerManager.getComponent("attachmentManager") as AttachmentManager 34 | def label = new Label(LABEL_VALUE) 35 | 36 | finalResult.each { 37 | labelManager.addLabel(attachmentManager.getAttachment(it.id.asLong()), label) 38 | } 39 | return "Done" -------------------------------------------------------------------------------- /src/main/confluence/СqlLabelAttachments1.groovy: -------------------------------------------------------------------------------- 1 | package confluence 2 | 3 | import com.atlassian.confluence.api.model.pagination.PageResponse 4 | import com.atlassian.confluence.api.model.pagination.SimplePageRequest 5 | import com.atlassian.confluence.api.service.search.CQLSearchService 6 | import com.atlassian.confluence.labels.Label 7 | import com.atlassian.confluence.labels.LabelManager 8 | import com.atlassian.confluence.pages.AttachmentManager 9 | import com.atlassian.plugin.osgi.container.OsgiContainerManager 10 | import com.atlassian.spring.container.ContainerManager 11 | import com.atlassian.confluence.api.model.content.Content 12 | 13 | final String LABEL_VALUE = "test_bulk_label" 14 | final String CQL_QUERY = "type = attachment and label != ${LABEL_VALUE} and lastmodified > 2019-11-14" 15 | final int MAX_ENTITIES = 500 16 | def label = new Label(LABEL_VALUE) 17 | 18 | def osgiContainerManager = ContainerManager.getComponent("osgiContainerManager") as OsgiContainerManager 19 | def cqlSearchService = osgiContainerManager.getServiceTracker(CQLSearchService.class.name).service as CQLSearchService 20 | 21 | def pageRequest = new SimplePageRequest(0, MAX_ENTITIES) 22 | def searchResult = cqlSearchService.searchContent(CQL_QUERY, pageRequest) as PageResponse 23 | searchResult.each { 24 | addLabel(label, it.id.asLong()) 25 | } 26 | def nextBatchStartIndex = searchResult.results.size() 27 | while (searchResult.hasMore()) { 28 | def nextPageRequest = new SimplePageRequest(nextBatchStartIndex, MAX_ENTITIES) 29 | searchResult = cqlSearchService.searchContent(CQL_QUERY, nextPageRequest) 30 | searchResult.each { 31 | addLabel(label, it.id.asLong()) 32 | } 33 | nextBatchStartIndex += searchResult.results.size() 34 | } 35 | return "Done" 36 | 37 | static def addLabel(Label label, Long id) { 38 | def labelManager = ContainerManager.getComponent("labelManager") as LabelManager 39 | def attachmentManager = ContainerManager.getComponent("attachmentManager") as AttachmentManager 40 | def attachment = attachmentManager.getAttachment(id) 41 | // if statement for confluence version < 7 - added by customer, not actual for us 42 | if (!attachment.getLabels().contains(label)) labelManager.addLabel(attachment, label) 43 | } -------------------------------------------------------------------------------- /src/main/confluence/СqlLabelPages.groovy: -------------------------------------------------------------------------------- 1 | package confluence 2 | 3 | import com.atlassian.confluence.api.model.pagination.PageResponse 4 | import com.atlassian.confluence.api.model.pagination.SimplePageRequest 5 | import com.atlassian.confluence.api.service.search.CQLSearchService 6 | import com.atlassian.confluence.labels.Label 7 | import com.atlassian.confluence.labels.LabelManager 8 | import com.atlassian.confluence.pages.PageManager 9 | import com.atlassian.plugin.osgi.container.OsgiContainerManager 10 | import com.atlassian.spring.container.ContainerManager 11 | import com.atlassian.confluence.api.model.content.Content 12 | 13 | final String CQL_QUERY = 'type = page and lastModified > "2020/07/15"' 14 | final String LABEL_VALUE = "content_page" 15 | final int MAX_ENTITIES = 500 16 | 17 | def osgiContainerManager = ContainerManager.getComponent("osgiContainerManager") as OsgiContainerManager 18 | def cqlSearchService = osgiContainerManager.getServiceTracker(CQLSearchService.class.name).service as CQLSearchService 19 | 20 | def numberOfResultsFound = cqlSearchService.countContent(CQL_QUERY) 21 | def finalResult = new ArrayList(numberOfResultsFound) 22 | def pageRequest = new SimplePageRequest(0, MAX_ENTITIES) 23 | def searchResult = cqlSearchService.searchContent(CQL_QUERY, pageRequest) as PageResponse 24 | finalResult.addAll(searchResult.results) 25 | 26 | while (searchResult.hasMore()) { 27 | def nextPageRequest = new SimplePageRequest(finalResult.size(), MAX_ENTITIES) 28 | searchResult = cqlSearchService.searchContent(CQL_QUERY, nextPageRequest) 29 | finalResult.addAll(searchResult.results) 30 | } 31 | 32 | def labelManager = ContainerManager.getComponent("labelManager") as LabelManager 33 | def pageManager = ContainerManager.getComponent("pageManager") as PageManager 34 | def label = new Label(LABEL_VALUE) 35 | 36 | finalResult.each { 37 | labelManager.addLabel(pageManager.getPage(it.id.asLong()), label) 38 | } 39 | return "Done" -------------------------------------------------------------------------------- /src/main/jira/REST_endpoints/GetBitBucketProjectNamesToSelectList.groovy: -------------------------------------------------------------------------------- 1 | package jira.REST_endpoints 2 | 3 | import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate 4 | import groovy.json.JsonBuilder 5 | import groovy.transform.BaseScript 6 | import groovyx.net.http.ContentType 7 | import groovyx.net.http.HTTPBuilder 8 | import groovyx.net.http.Method 9 | 10 | import javax.ws.rs.core.MultivaluedMap 11 | import javax.ws.rs.core.Response 12 | 13 | /* 14 | Select List Conversions 15 | https://scriptrunner.adaptavist.com/5.6.1/jira/behaviours-conversions.html 16 | */ 17 | 18 | @BaseScript CustomEndpointDelegate delegate 19 | 20 | bitbucketProjects(httpMethod: "GET") { MultivaluedMap queryParams -> 21 | 22 | def query = queryParams.getFirst("query") as String 23 | def baseURL = "" 24 | def rt = [:] 25 | if (query) { 26 | def url = "${baseURL}/rest/api/1.0/projects?name=${query}&limit=1000" 27 | def authRequest = new HTTPBuilder(url) 28 | def projects = authRequest.request(Method.GET, ContentType.JSON) { req -> 29 | req.setHeader("Content-Type", "application/json") 30 | req.setHeader("Authorization", "Basic user:pass IN base64" ) 31 | } 32 | if(projects){ 33 | List projectNames = projects["values"]*."name" 34 | rt = [ 35 | items: projectNames.collect { String project -> 36 | [ 37 | value: project, 38 | html : project.replaceAll(/(?i)${query}/) { "${it}" }, 39 | label: project, 40 | ] 41 | }, 42 | total: projects["total_count"], 43 | footer: "Choose repo... (${projectNames.size()} of ${projects["total_count"]} shown...)" 44 | ] 45 | return Response.ok(new JsonBuilder(rt).toString()).build() 46 | } 47 | else return Response.ok(new JsonBuilder(rt).toString()).build() 48 | } 49 | } 50 | 51 | /* Behaviour Initialiser 52 | getFieldByName("BitBucket Project").convertToSingleSelect([ 53 | ajaxOptions: [ 54 | url : getBaseUrl() + "/rest/scriptrunner/latest/custom/bitbucketProjects", 55 | query: true, // keep going back to the sever for each keystroke 56 | minQueryLength: 2, 57 | keyInputPeriod: 500, 58 | formatResponse: "general", 59 | ] 60 | ]) */ -------------------------------------------------------------------------------- /src/main/jira/behaviours/SetDescriptionBasedOnSelectListVal.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours 2 | 3 | import com.onresolve.jira.groovy.user.FieldBehaviours 4 | import groovy.transform.BaseScript 5 | 6 | @BaseScript FieldBehaviours fieldBehaviours 7 | 8 | def affectedField = getFieldById(getFieldChanged()) 9 | def affectedVal = affectedField.value 10 | def descriptionField = getFieldById("description") 11 | 12 | def defaultVal = "defaultVal" 13 | descriptionField.setFormValue(defaultVal) 14 | 15 | if (affectedVal instanceof String) { 16 | switch (affectedVal) { 17 | case "Performance": 18 | descriptionField.setFormValue("X") 19 | break 20 | case "Test": 21 | descriptionField.setFormValue("Y") 22 | break 23 | default: 24 | descriptionField.setFormValue(defaultVal) 25 | break 26 | } 27 | } else if (affectedVal instanceof List) { 28 | if (affectedVal == ["Performance", "Test 0"]) descriptionField.setFormValue("XX") 29 | else if (affectedVal == ["Test 0", "Test 1"]) descriptionField.setFormValue("YY") 30 | else descriptionField.setFormValue(defaultVal) 31 | } -------------------------------------------------------------------------------- /src/main/jira/behaviours/SetReporter.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours 2 | 3 | import com.onresolve.jira.groovy.user.FieldBehaviours 4 | import groovy.transform.BaseScript 5 | 6 | import static com.atlassian.jira.issue.IssueFieldConstants.* 7 | @BaseScript FieldBehaviours fieldBehaviours 8 | 9 | def reporter = getFieldById(REPORTER) 10 | def requester = getFieldById(fieldChanged) 11 | reporter.setFormValue(requester.value) 12 | reporter.setReadOnly(true) -------------------------------------------------------------------------------- /src/main/jira/behaviours/epic_lock/ClearErrorOnEpicLinkFieldDuringIssueTypeChange.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours.epic_lock 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.onresolve.jira.groovy.user.FieldBehaviours 5 | import groovy.transform.BaseScript 6 | 7 | @BaseScript FieldBehaviours fieldBehaviours 8 | 9 | def issueTypeField = getFieldById(getFieldChanged()) // issue type field 10 | def issueTypeFieldVal = issueTypeField.value as String 11 | def frIssueTypeId = ComponentAccessor.constantsManager.allIssueTypeObjects.find { 12 | it.name == "FR" 13 | }?.id 14 | 15 | if (issueTypeFieldVal != frIssueTypeId) { 16 | def epicLinkField = getFieldByName("Epic Link") 17 | epicLinkField.clearError() 18 | } -------------------------------------------------------------------------------- /src/main/jira/behaviours/epic_lock/DisableEditingBasedOnFieldVal.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours.epic_lock 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.IssueFieldConstants 5 | import com.onresolve.jira.groovy.user.FieldBehaviours 6 | import groovy.transform.BaseScript 7 | 8 | @BaseScript FieldBehaviours fieldBehaviours 9 | 10 | log.warn "### START OF LockedForChanges ###" 11 | log.warn "Working with ${underlyingIssue.issueType.name}" 12 | 13 | def lockedForChangeField = getFieldById(getFieldChanged()) // LockedForChange field 14 | def lockedForChangeFieldVal = lockedForChangeField.value as String 15 | 16 | def field = getFieldByName("LockedForChange") 17 | if (getFieldScreen().name == "PgM") field.setHidden(false) 18 | else field.setHidden(true) 19 | 20 | def systemFieldIds = IssueFieldConstants.fields.findResults { 21 | // apply changes to make field names similar to ids from front end 22 | it.name.toLowerCase().replace("_", "") 23 | } 24 | // system field names taken from backend differ from system field ids used in frontend for the fields below: 25 | systemFieldIds << "fixVersions" 26 | systemFieldIds << "versions" 27 | systemFieldIds.remove("comment") 28 | def customFieldsIds = ComponentAccessor.customFieldManager.getCustomFieldObjects(underlyingIssue)*.id 29 | customFieldsIds.remove(lockedForChangeField.fieldId) 30 | switch (lockedForChangeFieldVal) { 31 | case "Yes": 32 | systemFieldIds.each { 33 | getFieldById(it)?.setReadOnly(true) 34 | } 35 | customFieldsIds.each { 36 | getFieldById(it).setReadOnly(true) 37 | } 38 | getFieldById("attachment").setHidden(true) 39 | break 40 | default: 41 | systemFieldIds.each { 42 | getFieldById(it).setReadOnly(false) 43 | } 44 | customFieldsIds.each { 45 | getFieldById(it).setReadOnly(false) 46 | } 47 | break 48 | } -------------------------------------------------------------------------------- /src/main/jira/behaviours/epic_lock/HideLockIndicatorField.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours.epic_lock 2 | 3 | import com.onresolve.jira.groovy.user.FieldBehaviours 4 | import groovy.transform.BaseScript 5 | 6 | @BaseScript FieldBehaviours fieldBehaviours 7 | 8 | def lockedForChangeField = getFieldByName("LockedForChange") 9 | if (getFieldScreen().name == "PgM") lockedForChangeField.setHidden(false) 10 | else lockedForChangeField.setHidden(true) -------------------------------------------------------------------------------- /src/main/jira/behaviours/epic_lock/LimitLinkingToEpicFromChildBasedOnEpicFieldVal.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours.epic_lock 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 6 | import com.onresolve.jira.groovy.user.FieldBehaviours 7 | import groovy.transform.BaseScript 8 | 9 | @BaseScript FieldBehaviours fieldBehaviours 10 | 11 | final String epicLockFieldName = "LockedForChange" 12 | 13 | log.warn "### START OF EpicLockedForLinking ###" 14 | def epicLinkField = getFieldById(getFieldChanged()) //Epic Link 15 | def epicLinkFieldVal = epicLinkField.value as String 16 | if (!epicLinkFieldVal) return 17 | 18 | def epicKey = epicLinkFieldVal.substring(4) 19 | def epicIssue = ComponentAccessor.issueManager.getIssueObject(epicKey) 20 | def lockField = customFieldManager.customFieldObjects.find { it.name == epicLockFieldName } 21 | def lockedFieldVal = epicIssue.getCustomFieldValue(lockField) as List 22 | if (!lockedFieldVal) return 23 | def isEpicLocked = lockedFieldVal.any { it.value == "Yes" } 24 | // in case current issue belongs to locked Epic do not throw the error as it will block edits 25 | boolean isInEpic = false 26 | def issuesInEpic = getIssuesInEpic(epicIssue) 27 | if (!issuesInEpic.empty) { 28 | def keys = issuesInEpic*.key 29 | isInEpic = keys.any { it == underlyingIssue?.key } 30 | } 31 | 32 | if (isEpicLocked && !isInEpic && isFrIssueType) epicLinkField.setError("Epic ${epicKey} is locked") 33 | else epicLinkField.clearError() 34 | 35 | static List getIssuesInEpic(Issue epic) { 36 | ComponentAccessor.issueLinkManager.getOutwardLinks(epic.id). 37 | findAll { it.issueLinkType.name == "Epic-Story Link" }*.destinationObject 38 | } -------------------------------------------------------------------------------- /src/main/jira/behaviours/epic_lock/readme.md5: -------------------------------------------------------------------------------- 1 | Issue Type is Epic. Custom field - Checkbox type, name = "LockedForChange", Values = Yes\None (empty). 2 | “LockedForChange” can be set to “Yes” during specific transition via transition screen. 3 | 4 | ### When “LockedForChange” = “Yes” for Epic ###: 5 | - disable inline editing (all fields except Comments) in Epic and linked issue of FR issue type only; 6 | - disable adding links and adding Epic children; 7 | ### For linked issues of Issue Type FR, when the Epic has “LockedForChange” = “Yes" ###: 8 | - disable editing of FR type issues that are linked to Locked Epic (“LockedForChange” = “Yes”). 9 | ### Scripts ###: 10 | 1. [Behaviours] DisableEditingBasedOnFieldVal.groovy disables editing for Epic/FR; 11 | 2. [Behaviours] HideLockIndicatorField.groovy hides “LockedForChange” field. SR does not allow hiding checkbox field with empty value, when the script is 12 | attached to the same field. Current script solves the problem. Can be attached to any visible field, for example "Summary". 13 | 3. [Listener] jira/listeners/copy/SelectListValFromEpicToIssuesInEpic.groovy copies LockedForChange field val from Epic to linked FR issues 14 | in order to make DisableEditingBasedOnFieldVal.groovy script actual for linked FR issues too; 15 | 4. [Behaviours] LimitLinkingToEpicFromChildBasedOnEpicFieldVal.groovy does not allow linking to locked Epic (mapped to FR issue type only); 16 | 5. [Behaviours] ClearErrorOnEpicLinkFieldDuringIssueTypeChange.groovy is a workaround for clearing error in point 4 duting issue type change on 17 | on create transition; 18 | 6. [Fragments] jira/fragments/HideUiElementsBasedOnFieldValue.groovy for hiding UI elements in Epic. 19 | List of hidden elements: 20 | - com.atlassian.jira.plugin.system.issueoperations:clone-issue 21 | - com.atlassian.jira.plugin.system.issueoperations:create-subtask 22 | - com.atlassian.jira.plugin.system.issueoperations:delete-issue 23 | - com.atlassian.jira.plugin.system.issueoperations:edit-labels 24 | - com.atlassian.jira.plugin.system.issueoperations:issue-to-subtask 25 | - com.atlassian.jira.plugin.system.issueoperations:link-issue 26 | - com.atlassian.jira.plugin.system.issueoperations:move-issue -------------------------------------------------------------------------------- /src/main/jira/behaviours/insight/SetUserPickerAndDescription.groovy: -------------------------------------------------------------------------------- 1 | package jira.behaviours.insight 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.onresolve.jira.groovy.user.FieldBehaviours 5 | import com.onresolve.scriptrunner.runner.customisers.PluginModule 6 | import com.onresolve.scriptrunner.runner.customisers.WithPlugin 7 | import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade 8 | import groovy.transform.BaseScript 9 | 10 | @BaseScript FieldBehaviours fieldBehaviours 11 | 12 | @WithPlugin("com.riadalabs.jira.plugins.insight") 13 | @PluginModule 14 | ObjectFacade objectFacade 15 | 16 | def insightCf = getFieldByName("Договор") 17 | def serviceManagerField = getFieldByName("Сервис-менеджер") 18 | def descriptionField = getFieldById("description") 19 | if (insightCf.value) { 20 | def objectKey = insightCf.value as String 21 | // noinspection GroovyVariableNotAssigned 22 | def sppObject = objectFacade.loadObjectBean(objectKey) 23 | // set Service Manager 24 | def serviceManagerId = objectFacade.loadObjectAttributeBean(sppObject.id, "Сервис-менеджер"). 25 | objectAttributeValueBeans.first().referencedObjectBeanId 26 | def serviceManagerObject = objectFacade.loadObjectBean(serviceManagerId) 27 | def jiraUserKey = objectFacade.loadObjectAttributeBean(serviceManagerObject.id, "Профиль"). 28 | objectAttributeValueBeans.first().value as String 29 | def jiraUser = ComponentAccessor.userManager.getUserByKey(jiraUserKey) 30 | serviceManagerField.setFormValue(jiraUser.username) 31 | // set Description if it is empty 32 | if (!descriptionField.value) { 33 | def contractNumber = objectFacade.loadObjectAttributeBean(sppObject.id, "Номер договора"). 34 | objectAttributeValueBeans.first().value 35 | descriptionField.setFormValue(contractNumber) 36 | } 37 | } else { 38 | serviceManagerField.setFormValue("") 39 | descriptionField.setFormValue("") 40 | } -------------------------------------------------------------------------------- /src/main/jira/conditions/CheckBlockerStatus.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import org.apache.log4j.Logger 5 | import org.apache.log4j.Level 6 | 7 | if (issue.getProjectObject().name.equals("Testzigzag")) { 8 | def log = Logger.getLogger("check") 9 | log.setLevel(Level.DEBUG) 10 | def issueLinkManager = ComponentAccessor.getIssueLinkManager() 11 | def condition = true 12 | if (issue.getIssueType().name == "Task") { 13 | def blockers = issueLinkManager.getInwardLinks(issue.getId()).findAll { link -> link.getIssueLinkType().getId() == 10000 } 14 | blockers.each { blockerlink -> 15 | def blocker = blockerlink.getSourceObject() 16 | def blockerStatus = blocker.getStatus().name 17 | log.debug "$blocker is $blockerStatus" 18 | if (!(blockerStatus.equals('Resolved') || blockerStatus.equals('Verified') || blockerStatus.equals('Closed'))) { 19 | log.debug "$blocker block transition" 20 | condition = false 21 | } 22 | } 23 | return condition 24 | } 25 | } else return true -------------------------------------------------------------------------------- /src/main/jira/conditions/DisableForHighPriorityAndCertainCfVal.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import jira.JiraUtilHelper 4 | 5 | def insightCfVal = JiraUtilHelper.getCustomFieldValue("Подразделение", issue) as String 6 | if (!insightCfVal) return 7 | return !(insightCfVal == "[Технологический Центр Нудоль (ITSM-41)]" && issue.priority.name in ["Высокий"]) -------------------------------------------------------------------------------- /src/main/jira/conditions/DisableForLowPriority.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | return !(issue.priority.name in ["Низкий"]) 4 | 5 | -------------------------------------------------------------------------------- /src/main/jira/conditions/FieldValuesAsString.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | 6 | def requestTypeValue = getCustomFieldValue("Request Type", issue) as String 7 | def processTypeValue = getCustomFieldValue("Process Type", issue) as String 8 | 9 | return requestTypeValue == "New" && processTypeValue == "Analysis" 10 | 11 | static def getCustomFieldValue(String customFieldName, Issue issue) { 12 | ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { it.name == customFieldName }.getValue(issue) 13 | } -------------------------------------------------------------------------------- /src/main/jira/conditions/StatusLimitationBasedOnHistory.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | /**Used for status limitation on "Allow all transitions" transition. 6 | * Example of usage: 7 | * Status "Review before CE" has "allow all' transition; 8 | * Condition checks whether the issue is in required status (! from Pr., ! from PL, LC Translated); 9 | * Condition checks whether "Review before CE" status was in issue history; 10 | * if all passed - allows thw transition. 11 | */ 12 | 13 | def changeHistoryManager = ComponentAccessor.changeHistoryManager 14 | passesCondition = ( 15 | changeHistoryManager.getAllChangeItems(issue).any { 16 | it.field == "status" && "Review before CE" in it.fromValues.values() 17 | } 18 | && (issue.getStatus().getName().equals("! from Pr.") || 19 | issue.getStatus().getName().equals("! from PL") || 20 | issue.getStatus().getName().equals("LC Translated")) 21 | ) 22 | -------------------------------------------------------------------------------- /src/main/jira/conditions/SubTaskStateCondition.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def issue = ComponentAccessor.issueManager.getIssueObject(" ") //for testing in script console only 6 | 7 | def affectedSubTaskSummaries = ["Rule Go Live - Apply Soc Core Tag", "One Week Follow Up", 8 | "One Month Follow Up"].collect { it.toLowerCase() } 9 | def conditionSubTaskSummaries = ["Content Approval"].collect { it.toLowerCase() } 10 | def conditionStatus = "Approved" 11 | 12 | if (issue.summary.toLowerCase() in affectedSubTaskSummaries) { 13 | passesCondition = issue.parentObject.subTaskObjects.any { 14 | it.summary.toLowerCase() in conditionSubTaskSummaries && it.status.name == conditionStatus 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/jira/conditions/UserGroups.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 6 | def userUtil = ComponentAccessor.userUtil 7 | 8 | if (issue.parentObject.issueType.name == "Product Requirement") { 9 | passesCondition = userUtil.getGroupNamesForUser(currentUser.name).any{ 10 | it in ["product-owners", "scrum-masters"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/jira/conditions/UserRoles.groovy: -------------------------------------------------------------------------------- 1 | package jira.conditions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.security.roles.ProjectRoleManager 5 | 6 | final String [] ALLOWED_PROJECT_ROLES = ["Users"] 7 | 8 | def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager) 9 | projectRoleManager.getProjectRoles(currentUser, issue.projectObject)?.any { 10 | it.name in ALLOWED_PROJECT_ROLES 11 | } 12 | -------------------------------------------------------------------------------- /src/main/jira/escalation_services/AddLabel.groovy: -------------------------------------------------------------------------------- 1 | package jira.escalation_services 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.user.ApplicationUser 6 | import com.atlassian.jira.issue.label.LabelManager 7 | 8 | def archLabel = "archived_hide_from_tcc_board" 9 | 10 | static updateIssueLabels(ApplicationUser executionUser, String label, Issue issue) { 11 | def labelManager = ComponentAccessor.getComponentOfType(LabelManager) 12 | def existingLabels = labelManager.getLabels(issue.id)*.label 13 | def labelsToSet = (existingLabels + label).toSet() 14 | def sendNotification = false 15 | def issueUpdateEventAndReindex = true 16 | labelManager.setLabels(executionUser, issue.id, labelsToSet, sendNotification, issueUpdateEventAndReindex) 17 | } 18 | 19 | static List getIssuesInEpic(Issue epic) { 20 | ComponentAccessor.issueLinkManager.getOutwardLinks(epic.id). 21 | findAll { it.issueLinkType.name == "Epic-Story Link" }*.destinationObject 22 | } 23 | 24 | updateIssueLabels(currentUser, archLabel, issue) 25 | getIssuesInEpic(issue).each { updateIssueLabels(currentUser, archLabel, it) } -------------------------------------------------------------------------------- /src/main/jira/escalation_services/ClearFieldVal.groovy: -------------------------------------------------------------------------------- 1 | package jira.escalation_services 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.type.EventDispatchOption 5 | import com.atlassian.jira.issue.index.IssueIndexingService 6 | import com.atlassian.jira.util.ImportUtils 7 | 8 | final String SERVICE_ACCOUNT = "jira" 9 | final String AFFECTED_FIELD_NAME = "field" 10 | 11 | def issueManager = ComponentAccessor.issueManager 12 | def executionUser = ComponentAccessor.userManager.getUserByKey(SERVICE_ACCOUNT) 13 | def customField = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { it.name == AFFECTED_FIELD_NAME } 14 | 15 | if (!customField || !executionUser) return 16 | 17 | issue.setCustomFieldValue(customField, null) 18 | issueManager.updateIssue(executionUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false) 19 | def isIndexing = ImportUtils.isIndexIssues() 20 | ImportUtils.setIndexIssues(true) 21 | ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue) 22 | ImportUtils.setIndexIssues(isIndexing) -------------------------------------------------------------------------------- /src/main/jira/fragments/HideUiElementsBasedOnFieldValue.groovy: -------------------------------------------------------------------------------- 1 | package jira.fragments 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 5 | 6 | //If the condition is true then the UI element will be displayed. 7 | 8 | final String lockedField = "LockedForChange" 9 | final List allowed_issue_types = ["Epic", "FR"] 10 | 11 | if (issue.issueType.name in allowed_issue_types) { 12 | def customFieldManager = ComponentAccessor.customFieldManager 13 | def lockField = customFieldManager.customFieldObjects.find { it.name == lockedField } 14 | def lockedFieldVal = issue.getCustomFieldValue(lockField) as List 15 | if (lockedFieldVal?.any { it.value == "Yes" }) return false 16 | else true 17 | } else true -------------------------------------------------------------------------------- /src/main/jira/jobs/weeklyJQLReport.groovy: -------------------------------------------------------------------------------- 1 | package jira.jobs 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.onresolve.scriptrunner.runner.customisers.PluginModule 5 | import com.onresolve.scriptrunner.runner.customisers.WithPlugin 6 | import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade 7 | import jira.JiraUtilHelper 8 | import jira.ReportGenerator 9 | 10 | @WithPlugin("com.riadalabs.jira.plugins.insight") 11 | @PluginModule 12 | ObjectFacade objectFacade 13 | 14 | final Map insightContractKeys = ["P9127152":"ITSM-12", "P9117225":"ITSM-15"] 15 | final String EXECUTION_USER_NAME = "service_account" 16 | 17 | // noinspection GroovyVariableNotAssigned 18 | def getServiceManagerByInsightKey = { String key -> 19 | def serviceManager = objectFacade.loadObjectBean(key) 20 | def serviceManagerId = objectFacade.loadObjectAttributeBean(serviceManager.id, "Сервис-менеджер"). 21 | objectAttributeValueBeans.first().referencedObjectBeanId 22 | def serviceManagerObject = objectFacade.loadObjectBean(serviceManagerId) 23 | def jiraUserKey = objectFacade.loadObjectAttributeBean(serviceManagerObject.id, "Профиль"). 24 | objectAttributeValueBeans.first().textValue 25 | return ComponentAccessor.userManager.getUserByKey(jiraUserKey) 26 | } 27 | def executionUser = ComponentAccessor.userManager.getUserByName(EXECUTION_USER_NAME) 28 | 29 | insightContractKeys.each { k, v -> 30 | def emailAddress = getServiceManagerByInsightKey(v).emailAddress 31 | def jql = "project = ${k} and created >= \"-7d\"" 32 | def issues = JiraUtilHelper.getIssuesFromJql(executionUser, jql) 33 | def report = null 34 | def subject = null 35 | if (k == "P9127152") { 36 | report = ReportGenerator.generateDamageControlReport(issues) 37 | subject = "Еженедельная справка по оказанию услуг технической поддержки" 38 | } else if (k == "P9117225") { 39 | report = ReportGenerator.generateTechnicalReport(issues) 40 | subject = "Еженедельная справка по ремонтно-восстановительным работам" 41 | } 42 | // if (report) JiraUtilHelper.sendMail(emailAddress, subject, report) 43 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/AddFixVersionBasedOnLinkedIssue.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.issue.link.IssueLinkCreatedEvent 5 | import com.atlassian.jira.issue.Issue 6 | import com.atlassian.jira.issue.index.IssueIndexingService 7 | import com.atlassian.jira.util.ImportUtils 8 | 9 | def event = event as IssueLinkCreatedEvent 10 | def linkName = event.issueLink.issueLinkType.name 11 | def sourceIssue = event.issueLink.sourceObject as Issue //Test 12 | def destinationIssue = event.issueLink.destinationObject as Issue//Specification Version 13 | 14 | if (linkName == "Tests" && sourceIssue.issueType.name == "Test" && destinationIssue.issueType.name == "Specification Version") { 15 | def versionManager = ComponentAccessor.versionManager 16 | def sourceProjectFixVersionsNames = sourceIssue.projectObject.versions.collect { it.name } 17 | def destinationIssueFixVersionsNames = destinationIssue.fixVersions.collect { it.name } 18 | def versionsForUpdate = [] 19 | 20 | //no common fix version names 21 | if (sourceProjectFixVersionsNames.disjoint(destinationIssueFixVersionsNames)) { 22 | destinationIssue.fixVersions.each { fixVersion -> 23 | versionsForUpdate << versionManager.createVersion(fixVersion.name, fixVersion.startDate, fixVersion.releaseDate, 24 | fixVersion.description, sourceIssue.projectId, null, fixVersion.released) 25 | } 26 | //common fix version names 27 | } else { 28 | versionsForUpdate = sourceIssue.projectObject.versions?.findAll { it.name in destinationIssueFixVersionsNames } 29 | def versionsForCreation = destinationIssue.fixVersions.findAll { !sourceProjectFixVersionsNames.contains(it.name) } 30 | versionsForCreation.each { fixVersion -> 31 | versionsForUpdate << versionManager.createVersion(fixVersion.name, fixVersion.startDate, fixVersion.releaseDate, 32 | fixVersion.description, sourceIssue.projectId, null, fixVersion.released) 33 | } 34 | } 35 | versionsForUpdate.addAll(sourceIssue.fixVersions) 36 | versionManager.updateIssueFixVersions(sourceIssue, (Collection) versionsForUpdate) 37 | boolean wasIndexing = ImportUtils.isIndexIssues() 38 | ImportUtils.setIndexIssues(true) 39 | ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(sourceIssue) 40 | ImportUtils.setIndexIssues(wasIndexing) 41 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/AppendTextFromCfToCf.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.event.type.EventDispatchOption 6 | import com.atlassian.jira.issue.Issue 7 | import com.atlassian.jira.user.ApplicationUser 8 | import java.text.SimpleDateFormat 9 | 10 | def issue = event.issue 11 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 12 | 13 | def drbNotesValue = getCustomFieldValue("DRB Notes ", issue) 14 | if (!drbNotesValue) return 15 | 16 | def drbNotesAgrValue = getCustomFieldValue("DRB Notes (Aggregated)", issue) 17 | def drbContributorsValue = getCustomFieldValue("DRB Contributors", issue) as List 18 | 19 | def customValue = """ 20 | Noted on: ${new SimpleDateFormat("dd/MMM/yyyy").format(new Date())} \n 21 | By: ${user.displayName} \n 22 | Contributors: ${drbContributorsValue*.displayName} \n 23 | ${drbNotesValue} \n 24 | ========================== \n 25 | """ 26 | def builder = new StringBuilder() 27 | if (drbNotesAgrValue) builder.append(drbNotesAgrValue) 28 | builder.append(customValue) 29 | 30 | updateTextCf(user, issue, "DRB Notes (Aggregated)", builder.toString()) 31 | updateTextCf(user, issue, "DRB Notes ", null) 32 | updateTextCf(user, issue, "DRB Contributors", null) 33 | 34 | static def getCustomFieldValue(String customFieldName, Issue issue) { 35 | ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { it.name == customFieldName }?.getValue(issue) 36 | } 37 | 38 | static updateTextCf(ApplicationUser executionUser, Issue issue, String fieldName, String text) { 39 | def textFieldObject = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { it.name == fieldName } 40 | def issueService = ComponentAccessor.issueService 41 | def issueInputParameters = issueService.newIssueInputParameters() 42 | issueInputParameters.addCustomFieldValue(textFieldObject.id, text).setSkipScreenCheck(true) 43 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(executionUser, 44 | issue.id, issueInputParameters) 45 | if (validationResult.valid) 46 | issueService.update(executionUser, validationResult, EventDispatchOption.DO_NOT_DISPATCH, false) 47 | else validationResult.errorCollection 48 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/CheckAssigneeBasedOnHistory.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.history.ChangeItemBean 5 | /* 6 | Was used in listener "Fires an event when condition is true" 7 | */ 8 | //def issue = ComponentAccessor.issueManager.getIssueObject("BTP-29") as MutableIssue 9 | List history = ComponentAccessor.getChangeHistoryManager().getChangeItemsForField(issue, "assignee") 10 | 11 | if (history) { 12 | def previousAssignee = history.get(history.size() - 1).getFrom() 13 | def currentAssignee = history.get(history.size() - 1).getTo() 14 | return previousAssignee == "viktar" && currentAssignee != "viktar" 15 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/CopyCascadeDownSLFieldfromParentToAllChilds.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.issue.ModifiedValue 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.util.DefaultIssueChangeHolder 6 | 7 | def featureIssue = event.issue 8 | def customFieldManager = ComponentAccessor.getCustomFieldManager() 9 | def linkManager = ComponentAccessor.getIssueLinkManager() 10 | def roadmapQuaterField = customFieldManager.getCustomFieldObject(18903L); 11 | 12 | if (featureIssue.getIssueType().name == "Roadmap Feature") { 13 | 14 | def epicCollection = linkManager.getOutwardLinks(featureIssue.id) 15 | def epicIssue 16 | 17 | epicCollection.each { 18 | 19 | epicIssue = it.getDestinationObject() 20 | //modify epic 21 | def roadmapQuaterFieldValue = roadmapQuaterField.getValue(featureIssue) 22 | def modifiedValue = new ModifiedValue(null, roadmapQuaterFieldValue); 23 | roadmapQuaterField.updateValue(null, epicIssue, modifiedValue, new DefaultIssueChangeHolder()) 24 | //looking for stories 25 | def storiesCollection = linkManager.getOutwardLinks(epicIssue.id) 26 | def storyIssue 27 | 28 | storiesCollection.each{ 29 | //modify story 30 | storyIssue= it.getDestinationObject() 31 | roadmapQuaterFieldValue = roadmapQuaterField.getValue(epicIssue) 32 | modifiedValue = new ModifiedValue(null, roadmapQuaterFieldValue); 33 | roadmapQuaterField.updateValue(null, storyIssue, modifiedValue, new DefaultIssueChangeHolder()) 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/CopySLCFDuringIssueSplit.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.IssueInputParameters 6 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 7 | import com.atlassian.jira.issue.fields.CustomField 8 | import com.atlassian.jira.issue.link.IssueLink 9 | import com.atlassian.jira.user.ApplicationUser 10 | import com.atlassian.jira.event.issue.link.IssueLinkCreatedEvent 11 | 12 | String user = "tech_user" 13 | ApplicationUser applicationUser = ComponentAccessor.getUserManager().getUserByName(user) 14 | 15 | def event = event as IssueLinkCreatedEvent 16 | 17 | IssueLink splitLink = null 18 | 19 | if (event.getIssueLink().getIssueLinkType().getId() == 11000) splitLink = event.getIssueLink() 20 | 21 | CustomField bpTeam = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(18800L) 22 | LazyLoadedOption bpTeamValue = (LazyLoadedOption) splitLink.getSourceObject().getCustomFieldValue(bpTeam) 23 | 24 | if (splitLink != null && bpTeamValue != null) 25 | { 26 | IssueService issueService = ComponentAccessor.getIssueService() 27 | IssueInputParameters issueInputParameters = issueService.newIssueInputParameters() 28 | issueInputParameters.addCustomFieldValue(bpTeam.getIdAsLong(), bpTeamValue.getOptionId().toString()) 29 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(applicationUser, splitLink.getDestinationObject().getId(), issueInputParameters) 30 | 31 | if (validationResult.isValid()) issueService.update(applicationUser, validationResult) 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/jira/listeners/RemoveFixVersionBasedOnLinkedIssue.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.issue.link.IssueLinkDeletedEvent 5 | import com.atlassian.jira.issue.MutableIssue 6 | import com.atlassian.jira.issue.index.IssueIndexingService 7 | import com.atlassian.jira.util.ImportUtils 8 | 9 | def event = event as IssueLinkDeletedEvent 10 | def linkName = event.issueLink.issueLinkType.name 11 | def sourceIssue = event.issueLink.sourceObject as MutableIssue //Test 12 | def destinationIssue = event.issueLink.destinationObject as MutableIssue//Specification Version 13 | 14 | if (linkName == "Tests" && sourceIssue.issueType.name == "Test" && destinationIssue.issueType.name == "Specification Version") { 15 | def commonFixVersionsNames = sourceIssue.fixVersions.collect { 16 | it.name 17 | }.intersect(destinationIssue.fixVersions.collect { it.name }) 18 | def versionsForUpdate = sourceIssue.fixVersions 19 | versionsForUpdate.removeAll {it.name in commonFixVersionsNames} 20 | ComponentAccessor.versionManager.updateIssueFixVersions(sourceIssue, (Collection) versionsForUpdate) 21 | boolean wasIndexing = ImportUtils.isIndexIssues() 22 | ImportUtils.setIndexIssues(true) 23 | ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(sourceIssue) 24 | ImportUtils.setIndexIssues(wasIndexing) 25 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/SetCFValueBasedOnSprint.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import java.text.SimpleDateFormat 5 | 6 | def issue = event.issue 7 | def dateFormat = new SimpleDateFormat("dd/MMM/YY"); 8 | def sprintField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Sprint") 9 | def startSprintDate = dateFormat.format(sprintField.getValue(issue)[0].startDate.toDate()) 10 | def endSprintDate = dateFormat.format(sprintField.getValue(issue)[0].endDate.toDate()) 11 | updateDateCfWithHistory (startSprintDate, 16911L) 12 | updateDateCfWithHistory (endSprintDate, 16912L) 13 | 14 | void updateDateCfWithHistory(String stringDate, Long cf){ 15 | 16 | def issue = event.issue 17 | def updateDate = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(cf) 18 | 19 | if (updateDate.getValue(issue) == null) 20 | { 21 | 22 | def user = "tech_user" 23 | def applicationUser = ComponentAccessor.getUserManager().getUserByKey(user) 24 | def issueService = ComponentAccessor.getIssueService() 25 | def issueInputParameters = issueService.newIssueInputParameters() 26 | issueInputParameters.addCustomFieldValue(updateDate.getIdAsLong(), stringDate) 27 | def validationResult = issueService.validateUpdate(applicationUser, issue.getId(), issueInputParameters) 28 | 29 | if (validationResult.isValid()) { 30 | issueService.update(applicationUser, validationResult) 31 | } 32 | } 33 | } 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/jira/listeners/SetSelectListFieldBasedOnAssignee.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.issue.ModifiedValue 4 | import com.atlassian.jira.issue.util.DefaultIssueChangeHolder 5 | import com.atlassian.jira.component.ComponentAccessor 6 | 7 | def underlyingIssue = event.issue 8 | def customFieldManager = ComponentAccessor.getCustomFieldManager() 9 | def optionsManager = ComponentAccessor.getOptionsManager() 10 | def userUtil = ComponentAccessor.getUserUtil() 11 | 12 | def bp_team = customFieldManager.getCustomFieldObject(18800L) 13 | def fieldConfig = bp_team.getRelevantConfig(underlyingIssue) 14 | def value 15 | 16 | def groups = userUtil.getGroupsForUser(underlyingIssue.getAssignee().getName()) 17 | 18 | Map keys = new HashMap() 19 | keys.put("TEST.Riders","TEST - Riders" ) 20 | keys.put("TEST.FizzyBubblech", "TEST - Fizzy Bubblech" ) 21 | keys.put("TEST.Springularity", "TEST - Springularity" ) 22 | keys.put("TEST.Llamas", "TEST - Victorious Steel Llamas") 23 | keys.put("TEST.Mossad", "TEST - Mossad" ) 24 | keys.put("TEST.Cellardoor", "TEST - Cellardoor" ) 25 | keys.put("TEST.Parsley", "TEST - Mysterious tufts of Parsley" ) 26 | keys.put("TEST.MobyDick", "TEST - Moby Dick") 27 | keys.put("TEST.HouseStack", "TEST - House of Stack") 28 | keys.put("TEST.SleepingThreads", "TEST - Sleeping Threads" ) 29 | keys.put("TEST.Hammerhood", "TEST - Hammerhood" ) 30 | keys.put("TEST.Bamboleo", "TEST - Bamboleo" ) 31 | keys.put("TEST.tnt", "TEST - TNT" ) 32 | keys.put("TEST.Skynet" , "TEST - Skynet" ) 33 | 34 | groups.each{ 35 | 36 | def oneGroup = it.getName() 37 | 38 | keys.each{ k, v -> 39 | if(oneGroup.equals(k)){ 40 | value = ComponentAccessor.optionsManager.getOptions(fieldConfig)?.find { it.toString() == v} 41 | bp_team.updateValue(null, underlyingIssue, new ModifiedValue(null, value), new DefaultIssueChangeHolder()) 42 | return 43 | } 44 | } 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/jira/listeners/UpdateLableInLinkedIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.issue.IssueEvent 5 | import com.atlassian.jira.issue.label.LabelManager 6 | import com.atlassian.jira.issue.link.IssueLink 7 | import org.ofbiz.core.entity.GenericValue 8 | 9 | def issueUpdateEvent = event as IssueEvent 10 | def issue = issueUpdateEvent.issue 11 | if (issue.issueType.name == "Story") { 12 | GenericValue change = issueUpdateEvent?.changeLog?.getRelated("ChildChangeItem")?.find { genericValue -> 13 | genericValue.get("field") == "labels" 14 | } 15 | if (change) { 16 | def oldLabels = change.get("oldstring").toString().split() 17 | def newLabels = change.get("newstring").toString().split() 18 | def labelsForLinkedIssues = newLabels.findAll { !(it in oldLabels) } 19 | if (labelsForLinkedIssues) { 20 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 21 | def labelManager = ComponentAccessor.getComponent(LabelManager.class) 22 | ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id).each { IssueLink issueLink -> 23 | labelsForLinkedIssues.each { 24 | labelManager.addLabel(user, issueLink.destinationObject.id, it, false) 25 | } 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/UpdateOfLinkedIssuesCFBasedOnParentHistory.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import java.text.SimpleDateFormat 5 | 6 | def issue = event.issue 7 | def changeHistoryManager = ComponentAccessor.getChangeHistoryManager() 8 | def linkManager = ComponentAccessor.getIssueLinkManager() 9 | int changeID = changeHistoryManager.getAllChangeItems(issue).get(changeHistoryManager.getAllChangeItems(issue).size()-1).changeGroupId 10 | def listUpdated = changeHistoryManager.getChangeHistoryById(changeID).getChangeItemBeans() 11 | def catchedChange = listUpdated.find{ it.field == 'Start date' } 12 | if (catchedChange != null){ 13 | 14 | def childCollection = linkManager.getOutwardLinks(issue.id) 15 | if (childCollection!=null){ 16 | 17 | def childIssue 18 | childCollection.each { 19 | if (it.getIssueLinkType().outward == 'SF-depends on'){ 20 | 21 | childIssue = it.getDestinationObject() 22 | CopyValue(issue,childIssue,16911L) 23 | } 24 | } 25 | } 26 | } 27 | 28 | def CopyValue(def outIssue, def inIssue, Long Field){ 29 | def updateDate = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(Field) 30 | def user = "tech_user" 31 | def applicationUser = ComponentAccessor.getUserManager().getUserByKey(user) 32 | def issueService = ComponentAccessor.getIssueService() 33 | def issueInputParameters = issueService.newIssueInputParameters() 34 | def dateFormat = new SimpleDateFormat("dd/MMM/YY") 35 | Calendar createdDate = Calendar.getInstance() 36 | createdDate.setTime(updateDate.getValue(outIssue)) 37 | def startDate = dateFormat.format(updateDate.getValue(outIssue)) 38 | issueInputParameters.addCustomFieldValue(updateDate.getIdAsLong(),startDate ) 39 | def validationResult = issueService.validateUpdate(applicationUser, inIssue.getId(), issueInputParameters) 40 | if (validationResult.isValid()) { 41 | issueService.update(applicationUser, validationResult).hasWarnings() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/jira/listeners/copy/CommentAttachmentToLinkedInwardIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners.copy 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import org.apache.log4j.Logger 5 | import org.apache.log4j.Level 6 | import org.ofbiz.core.entity.GenericValue 7 | 8 | /** 9 | * Events: issue updated, issue commented, generic event 10 | */ 11 | 12 | def logger = Logger.getLogger("test-me-pls") 13 | logger.setLevel(Level.DEBUG) 14 | 15 | def attachmentIds = [] 16 | def changeItems = event.changeLog?.getRelated("ChildChangeItem") as List 17 | if (changeItems) changeItems.each { GenericValue genericValue -> 18 | if (genericValue["field"] == "Attachment" && genericValue["newvalue"]) attachmentIds << genericValue["newvalue"] 19 | } 20 | logger.debug(event.changeLog?.getRelated("ChildChangeItem")) 21 | logger.debug(attachmentIds) 22 | 23 | def executionUser = ComponentAccessor.userManager.getUserByName("sr_automation") 24 | def inwardIssues = ComponentAccessor.issueLinkManager.getInwardLinks(event.issue.id).collect {it.sourceObject} 25 | if (!attachmentIds.empty && !inwardIssues.empty) { 26 | def attachmentManager = ComponentAccessor.attachmentManager 27 | def attachments = attachmentIds.collect { attachmentManager.getAttachment(it as Long) } 28 | inwardIssues.each { issue -> 29 | attachments.each { attachment -> attachmentManager.copyAttachment(attachment, executionUser, issue.key)} 30 | } 31 | } 32 | 33 | if (event.comment && !inwardIssues.empty) { 34 | def originalAuthor = event.comment.authorApplicationUser.name 35 | def originalBody = event.comment.body 36 | def newBody = """Author: ${originalAuthor} 37 | ${originalBody} 38 | """ 39 | def commentManager = ComponentAccessor.commentManager 40 | inwardIssues.each { 41 | commentManager.create(it, executionUser, newBody, true) 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/copy/CommentAttachmentToLinkedOutwardIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners.copy 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.MutableIssue 5 | 6 | def commentMgr = ComponentAccessor.commentManager 7 | def issue = event.issue as MutableIssue 8 | 9 | // gather the original author and comment body from the original issues comment 10 | def type = issue.issueType.name 11 | def newComment = event.comment 12 | def originalAuthor = newComment.authorApplicationUser 13 | def commentBody = newComment.body 14 | 15 | // get original issue's linked issues and create comment on the linked issue 16 | if (commentBody && type == "Task") { 17 | def attacher = ComponentAccessor.attachmentManager 18 | def linker = ComponentAccessor.issueLinkManager 19 | def sourceAttaches = attacher.getAttachments(issue) 20 | 21 | //iterate over the issues linked to the current issue through 22 | linker.getOutwardLinks(issue.id).each { outwardLink -> 23 | def destinationIssue = outwardLink.destinationObject 24 | //copy comment 25 | commentMgr.create(destinationIssue, originalAuthor, commentBody , true) 26 | //get attachments from linked issue 27 | def linkedAttaches = attacher.getAttachments(destinationIssue) 28 | //check if this attachment from the linked issue already exists on the current issue 29 | //and if not exists copy it to the linked issue 30 | if (sourceAttaches) sourceAttaches.each{ sourceAttach -> 31 | if (!linkedAttaches.find { linkedAttach -> 32 | sourceAttach.filename == linkedAttach.filename && 33 | sourceAttach.filesize == linkedAttach.filesize && 34 | sourceAttach.mimetype == linkedAttach.mimetype 35 | }) attacher.copyAttachment(sourceAttach, originalAuthor, destinationIssue.key) 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/copy/SelectListValFromEpicToIssuesInEpic.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners.copy 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.type.EventDispatchOption 5 | import com.atlassian.jira.issue.Issue 6 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 7 | 8 | final String LOCK_FIELD_NAME = "LockedForChange" 9 | final List ALLOWED_ISSUE_TYPES_IN_EPIC = ["FR"] 10 | 11 | //condition 12 | def issue = event.issue 13 | if (issue.issueType.name != "Epic") return 14 | def changeItems = event.changeLog.getRelated("ChildChangeItem") 15 | if (!changeItems?.any { it.field.toString().equalsIgnoreCase(LOCK_FIELD_NAME) }) return 16 | 17 | def issueManager = ComponentAccessor.issueManager 18 | def customFieldManager = ComponentAccessor.customFieldManager 19 | def executionUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 20 | def lockField = customFieldManager.customFieldObjects.find { it.name == LOCK_FIELD_NAME } 21 | 22 | def lockedFieldVal = issue.getCustomFieldValue(lockField) as List 23 | def issuesInEpic = getIssuesInEpic(issue) 24 | if (issuesInEpic.empty) return 25 | 26 | def affectedIssueKeys = issuesInEpic?.findResults { if (it.issueType.name in ALLOWED_ISSUE_TYPES_IN_EPIC) return it.key } 27 | affectedIssueKeys.each { 28 | def mutableIssue = issueManager.getIssueObject(it) 29 | mutableIssue.setCustomFieldValue(lockField, lockedFieldVal) 30 | issueManager.updateIssue(executionUser, mutableIssue, EventDispatchOption.DO_NOT_DISPATCH, false) 31 | } 32 | 33 | static List getIssuesInEpic(Issue epic) { 34 | ComponentAccessor.issueLinkManager.getOutwardLinks(epic.id). 35 | findAll { it.issueLinkType.name == "Epic-Story Link" }*.destinationObject 36 | } -------------------------------------------------------------------------------- /src/main/jira/listeners/set_field_based_on/PriorityChange.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners.set_field_based_on 2 | 3 | import JiraUtilHelper 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | def wasPriorityUpdated = event.changeLog.getRelated("ChildChangeItem") 7 | .any{ it.field.toString().equalsIgnoreCase("priority") } 8 | if (!wasPriorityUpdated) return 9 | 10 | def issue = event.issue 11 | def executionUser = ComponentAccessor.userManager.getUserByName("automation") 12 | def targetFieldName = "Ручная установка приоритета" 13 | def conditionFieldName = "Тип обращения" 14 | 15 | def targetFieldVal = JiraUtilHelper.getCustomFieldValue(targetFieldName, issue) as String 16 | if (targetFieldVal == "Да") return 17 | def conditionFieldVal = JiraUtilHelper.getCustomFieldValue(conditionFieldName, issue) as String 18 | if (conditionFieldVal != "Системная проблема") return 19 | 20 | def field = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue) 21 | .find { it.name == targetFieldName} 22 | JiraUtilHelper.setSingleSelectListValue(issue, "Да", field, executionUser) -------------------------------------------------------------------------------- /src/main/jira/listeners/set_field_based_on/StatusCategory.groovy: -------------------------------------------------------------------------------- 1 | package jira.listeners.set_field_based_on 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import java.text.SimpleDateFormat 6 | 7 | def issue = event.issue 8 | if (issue.issueType.name != "Task") return 9 | log.info "Working with ${issue}" 10 | def actualStartDate = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 11 | it.name == "Actual Start Date" } 12 | def actualStartDateValue = actualStartDate?.getValue(issue) 13 | if (!actualStartDateValue && issue.status.statusCategory.name == "In Progress") { 14 | def executionUser = ComponentAccessor.userManager.getUserByName("tech_user") 15 | def issueService = ComponentAccessor.issueService 16 | def issueInputParameters = issueService.newIssueInputParameters() 17 | issueInputParameters.addCustomFieldValue(actualStartDate.id, 18 | new SimpleDateFormat("dd/MMM/YY").format(new Date())).setSkipScreenCheck(true) 19 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(executionUser, 20 | issue.id, issueInputParameters) 21 | log.info "Validation result: ${validationResult.valid}" 22 | if (validationResult.valid) issueService.update(executionUser, validationResult).errorCollection 23 | else log.info validationResult.errorCollection.toString() 24 | } else log.info "Condition status: " + (!actualStartDateValue && issue.status.statusCategory.name == "In Progress") -------------------------------------------------------------------------------- /src/main/jira/post_functions/AddRemoteLinkFromCFtoIssue.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.CustomFieldManager 5 | import com.atlassian.jira.issue.MutableIssue 6 | import com.atlassian.jira.issue.fields.CustomField 7 | import com.atlassian.jira.issue.link.RemoteIssueLinkBuilder 8 | import com.atlassian.jira.issue.link.RemoteIssueLinkManager 9 | import org.apache.log4j.Level 10 | import org.apache.log4j.Logger 11 | 12 | RemoteLinks script = new RemoteLinks() 13 | script.run(issue) 14 | 15 | class RemoteLinks { 16 | Logger log = Logger.getLogger("Create Remote links to Issue") 17 | long ScriptStartTime = System.currentTimeMillis() 18 | def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() 19 | def issueManager = ComponentAccessor.getIssueManager() 20 | def strCFIdIssueLinks = "Issue Links" 21 | CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager() 22 | void run(MutableIssue issue) { 23 | log.setLevel(Level.DEBUG) 24 | log.debug("${issue.key} Script started") 25 | long ScriptStartTime = System.currentTimeMillis() 26 | CustomField linksCF = customFieldManager.getCustomFieldObjectsByName(strCFIdIssueLinks).iterator().next() 27 | def stringlinks = issue.getCustomFieldValue(linksCF) 28 | def links = stringlinks.split() 29 | for (slink in links){ 30 | if(slink != "") 31 | { 32 | try{ 33 | def linkBuilder = new RemoteIssueLinkBuilder() 34 | linkBuilder.issueId(issue.id) 35 | linkBuilder.relationship("ECM") 36 | linkBuilder.title("Vendor site") 37 | linkBuilder.url(slink) 38 | def link = linkBuilder.build() 39 | ComponentAccessor.getComponent(RemoteIssueLinkManager).createRemoteIssueLink(link, user) 40 | }catch (Exception ex) {} 41 | } 42 | } 43 | long ScriptWorkTime = System.currentTimeMillis() - ScriptStartTime 44 | log.debug("${issue.key} Script work time: ${ScriptWorkTime} ms.") 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/AllSubTasksAreClosed.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | /* 6 | This snippet was used in JMWE addon as condition for post-function transit parent issue. 7 | Issue type HEC Report is sub-task 8 | */ 9 | 10 | def linkedHecReports = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.parentObject.id).findAll { 11 | it.destinationObject.issueType.name == "HEC Report"} 12 | 13 | if (linkedHecReports.size() > 1) { 14 | if (linkedHecReports.findAll{ it.destinationObject.status.name == "Closed"}.size() == linkedHecReports.size()) true 15 | else false 16 | } else true 17 | 18 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/AssignBasedOnHistoryStatus.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.type.EventDispatchOption 5 | 6 | def changeHistoryManager = ComponentAccessor.changeHistoryManager 7 | def userManager = ComponentAccessor.userManager 8 | def issueManager = ComponentAccessor.issueManager 9 | def executionUser = userManager.getUserByName("automation") 10 | 11 | def statusChanges = changeHistoryManager.getAllChangeItems(issue).findResults { change -> 12 | if (change.field == "status" && "Уточнение информации" in change.tos.values()) return change 13 | } 14 | def lastStatusChange = statusChanges.sort { it.created }.last() 15 | def lastChanger = lastStatusChange.userKey 16 | // fix for renamed users 17 | def user = userManager.getUserByKey(lastChanger) 18 | def mutableIssue = issueManager.getIssueObject(issue.id) 19 | 20 | mutableIssue.setAssignee(user) 21 | issueManager.updateIssue(executionUser, mutableIssue, EventDispatchOption.DO_NOT_DISPATCH, false) -------------------------------------------------------------------------------- /src/main/jira/post_functions/ChangeIssueTypeBasedOnFieldValues.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import org.apache.log4j.Level 5 | import org.apache.log4j.Logger 6 | 7 | def issue = ComponentAccessor.issueManager.getIssueObject("PFT-29") 8 | def log = Logger.getLogger("check-me") 9 | log.setLevel(Level.DEBUG) 10 | 11 | if (issue.issueType.name == "Story") { 12 | def epicIssueTypeId = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(issue.projectObject) 13 | .find{it.name == "Epic"}.id 14 | if (epicIssueTypeId) { 15 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 16 | def issueService = ComponentAccessor.issueService 17 | def issueInputParameters = issueService.newIssueInputParameters() 18 | issueInputParameters.setIssueTypeId(epicIssueTypeId) 19 | def updateValidationResult = issueService.validateUpdate(user, issue.id, issueInputParameters) 20 | if (updateValidationResult.valid) issueService.update(user, updateValidationResult) 21 | else log.debug(updateValidationResult.errorCollection.errors) 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/CheckIssueWithSameSummaryAndLinkIt.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.bc.issue.search.SearchService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | import com.atlassian.jira.issue.search.SearchResults 7 | import com.atlassian.jira.user.ApplicationUser 8 | import com.atlassian.jira.web.bean.PagerFilter 9 | 10 | String sourceSummary = issue.summary 11 | 12 | String user = "admin" 13 | String jqlQuery = "project = PELATEST and summary ~ '" + sourceSummary + "' order by key desc" 14 | 15 | def searchService = ComponentAccessor.getComponentOfType(SearchService.class) 16 | def userManager = ComponentAccessor.getUserManager() 17 | ApplicationUser applicationUser = userManager.getUserByKey(user) 18 | 19 | //get issues from JQL query 20 | final SearchService.ParseResult parseResult = searchService.parseQuery(applicationUser, jqlQuery) 21 | List issues = new ArrayList<>() 22 | if (parseResult.isValid()) { 23 | final SearchResults results = searchService.search(applicationUser, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) 24 | issues = results.getIssues() 25 | } 26 | 27 | List destinationIssues = new ArrayList<>() 28 | 29 | if (issues.size() > 1) { 30 | issues.remove(0) 31 | destinationIssues = issues.findAll{it.summary==sourceSummary} 32 | } 33 | 34 | if (destinationIssues.size() > 0) { 35 | def isssueLinkManager = ComponentAccessor.issueLinkManager 36 | destinationIssues.each { 37 | isssueLinkManager.createIssueLink(issue.getId(), it.getId(), 10003L, 1L, applicationUser) //10001 - id of clone link 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/CopyIssueLinksFromSubTaskToParentScreen.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.fields.IssueLinksSystemField 5 | import com.atlassian.jira.issue.link.IssueLinkTypeManager 6 | import webwork.action.ActionContext 7 | 8 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 9 | def linkManager = ComponentAccessor.issueLinkManager 10 | 11 | def childInwardLinks = linkManager.getInwardLinks(issue.id).findAll {it.issueLinkType.name != "jira_subtask_link"} 12 | if (childInwardLinks) { 13 | childInwardLinks.each { 14 | linkManager.createIssueLink(it.sourceObject.id, issue.parentObject.id, it.issueLinkType.id, it.sequence, currentUser) 15 | } 16 | } 17 | def childOutwardsLinks = linkManager.getOutwardLinks(issue.id) 18 | if (childOutwardsLinks) { 19 | childOutwardsLinks.each { 20 | linkManager.createIssueLink(issue.parentObject.id, it.destinationObject.id, it.issueLinkType.id, it.sequence, currentUser) 21 | } 22 | } 23 | //screen 24 | def linksSystemField = ComponentAccessor.fieldManager.getField("issuelinks") as IssueLinksSystemField 25 | def request = ActionContext.request 26 | if (request) { 27 | def params = request.parameterMap 28 | def issueLinkingValue = linksSystemField.getRelevantParams(params) as IssueLinksSystemField.IssueLinkingValue 29 | if (issueLinkingValue.linkedIssues) { 30 | def issueLinkTypeManager = ComponentAccessor.getComponentOfType(IssueLinkTypeManager.class) 31 | def linkedIssuesObjects = issueLinkingValue.linkedIssues.collect { 32 | ComponentAccessor.issueManager.getIssueObject(it) 33 | } 34 | def isInwardLink = issueLinkTypeManager.issueLinkTypes.any { it.inward == issueLinkingValue.linkDescription } 35 | if (isInwardLink) { 36 | def issueLinkType = issueLinkTypeManager.issueLinkTypes.find { 37 | it.inward == issueLinkingValue.linkDescription 38 | } 39 | linkedIssuesObjects.each { 40 | linkManager.createIssueLink(it.id, issue.parentObject.id, issueLinkType.id, 0, currentUser) 41 | } 42 | } else { 43 | def issueLinkType = issueLinkTypeManager.issueLinkTypes.find { 44 | it.outward == issueLinkingValue.linkDescription 45 | } 46 | linkedIssuesObjects.each { 47 | linkManager.createIssueLink(issue.parentObject.id, it.id, issueLinkType.id, 0, currentUser) 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/CopySelectListCFValueWithinTheSameIssue.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | def sourceSLField = ComponentAccessor.customFieldManager.getCustomFieldObject(10705l) 7 | def sourceValue = sourceSLField.getValue(issue) 8 | def destSLField = ComponentAccessor.customFieldManager.getCustomFieldObject(10803l) 9 | def destValue = destSLField.getValue(issue) 10 | 11 | if (sourceValue && !destValue) { 12 | def optionToSelect = ComponentAccessor.optionsManager.getOptions(destSLField.getRelevantConfig(issue)) 13 | .find {it.value == sourceValue.toString()} 14 | 15 | if (optionToSelect) { 16 | def issueService = ComponentAccessor.issueService 17 | def issueInputParameters = issueService.newIssueInputParameters() 18 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 19 | issueInputParameters.addCustomFieldValue(destSLField.idAsLong, optionToSelect.optionId.toString()) 20 | .setSkipScreenCheck(true) 21 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters) 22 | if (validationResult.valid) issueService.update(currentUser, validationResult) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/CopySelectListCfValueFromParentToSubtask.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | import com.atlassian.jira.issue.IssueInputParameters 7 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 8 | import com.atlassian.jira.issue.fields.CustomField 9 | import com.atlassian.jira.user.ApplicationUser 10 | 11 | String user = "tech_user"; 12 | ApplicationUser applicationUser = ComponentAccessor.getUserManager().getUserByKey(user); 13 | 14 | Issue parentIssue = issue.getParentObject(); 15 | CustomField bpTeam = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(18800L); 16 | LazyLoadedOption value = (LazyLoadedOption) parentIssue.getCustomFieldValue(bpTeam); 17 | 18 | if (issue.getCustomFieldValue(bpTeam) == null) 19 | { 20 | IssueService issueService = ComponentAccessor.getIssueService(); 21 | IssueInputParameters issueInputParameters = issueService.newIssueInputParameters(); 22 | issueInputParameters.addCustomFieldValue(bpTeam.getIdAsLong(), value.getOptionId().toString()); 23 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(applicationUser, issue.getId(), issueInputParameters); 24 | if (validationResult.isValid()) IssueService.IssueResult result = issueService.update(applicationUser, validationResult); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/FindIssuesTransitUpdateCF.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.MutableIssue 5 | import com.atlassian.jira.issue.fields.CustomField 6 | 7 | def issueService = ComponentAccessor.issueService 8 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 9 | def issueManager = ComponentAccessor.issueManager 10 | def smartClonedFromField = ComponentAccessor.customFieldManager.getCustomFieldObject(10400) 11 | def inProductTestField = ComponentAccessor.customFieldManager.getCustomFieldObject(10500) 12 | def transitionId = 171 13 | def maxAllowedLoop = 60 14 | def updateStringField = { CustomField field, MutableIssue localIssue, String value -> 15 | def inputParameters = issueService.newIssueInputParameters() 16 | inputParameters.addCustomFieldValue(field.id, value).setSkipScreenCheck(true) 17 | def validationResult = issueService.validateUpdate(user, localIssue.id, inputParameters) 18 | if (validationResult.isValid()) { 19 | issueService.update(user, validationResult) 20 | } else { 21 | log.warn("update errors " + validationResult.errorCollection) 22 | } 23 | } 24 | 25 | def transitIssueToReplace = { MutableIssue localIssue -> 26 | def transitionValidationResult = issueService.validateTransition(user, localIssue.id, transitionId, 27 | issueService.newIssueInputParameters()) 28 | if (transitionValidationResult.isValid()) { 29 | issueService.transition(user, transitionValidationResult) 30 | } else { 31 | log.warn("transition errors " + transitionValidationResult.errorCollection) 32 | } 33 | } 34 | 35 | updateStringField(inProductTestField, issue, issue.key) 36 | def issueForTransition = issueManager?.getIssueObject(smartClonedFromField?.getValueFromIssue(issue) as String) 37 | def counter = 0 38 | 39 | if (issueForTransition) { 40 | counter++ 41 | transitIssueToReplace(issueForTransition) 42 | updateStringField(inProductTestField, issueForTransition, issue.key) 43 | def isRunning = true 44 | while (isRunning) { 45 | issueForTransition = issueManager?.getIssueObject(issueForTransition?.getCustomFieldValue(smartClonedFromField) as String) 46 | if (issueForTransition == null || issueForTransition.key == issue.key || counter > maxAllowedLoop) isRunning = false 47 | if (issueForTransition) { 48 | transitIssueToReplace(issueForTransition) 49 | updateStringField(inProductTestField, issueForTransition, issue.key) 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/GroupPickerCfUpdate.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.ModifiedValue 5 | import com.atlassian.jira.issue.util.DefaultIssueChangeHolder 6 | import com.atlassian.jira.issue.util.IssueChangeHolder 7 | 8 | /* 9 | Updates multi group picker fields depending on issue type 10 | */ 11 | def cfManager = ComponentAccessor.customFieldManager 12 | def groupManager = ComponentAccessor.groupManager 13 | def readCf = cfManager.getCustomFieldObject(11102) 14 | def updateCf = cfManager.getCustomFieldObject(11103) 15 | def issueType = issue.issueType.name 16 | IssueChangeHolder changeHolder = new DefaultIssueChangeHolder() 17 | 18 | switch (issueType) { 19 | case "Incident": 20 | def groups = [groupManager.getGroup("Xtremax"), groupManager.getGroup("GVT"), groupManager.getGroup("AM"), 21 | groupManager.getGroup("AA"), groupManager.getGroup("CA"), groupManager.getGroup("Finance"), 22 | groupManager.getGroup("SIRO")] 23 | readCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(readCf), groups), changeHolder) 24 | updateCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(updateCf), groups), changeHolder) 25 | break 26 | case "Problem": 27 | case "Change": 28 | def groups = [groupManager.getGroup("Xtremax"), groupManager.getGroup("GVT")] 29 | readCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(readCf), groups), changeHolder) 30 | updateCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(updateCf), groups), changeHolder) 31 | break 32 | case "Service Request": 33 | def readGroups = [groupManager.getGroup("Xtremax"), groupManager.getGroup("GVT"), groupManager.getGroup("AM"), 34 | groupManager.getGroup("AA"), groupManager.getGroup("CA"), groupManager.getGroup("Finance"), 35 | groupManager.getGroup("SIRO")] 36 | readCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(readCf), readGroups), changeHolder) 37 | def updateGroups = [groupManager.getGroup("Xtremax"), groupManager.getGroup("GVT"), groupManager.getGroup("AM"), 38 | groupManager.getGroup("AA"), groupManager.getGroup("CA")] 39 | updateCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(updateCf), updateGroups), changeHolder) 40 | break 41 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/JenkinsTriggerJob.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | def issuekey=issue.getKey() 4 | def issueReporter=issue.getReporter() 5 | def issueReporterMail=issueReporter.getEmailAddress() 6 | 7 | 8 | def baseurl = "http://jenkins/buildByToken/buildWithParameters?job=auto_actionitems/dbauto_actionitems_single_ticket&token=singletickettoken&environment=all_lower&ticket=${issuekey}&email=${issueReporterMail}&cause=jira_workflow_trigger" 9 | 10 | def connection=new URL(baseurl).openConnection() as HttpURLConnection 11 | connection.setRequestMethod( "POST" ) 12 | connection.doOutput = true 13 | connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8") 14 | connection.getOutputStream().write() 15 | connection.connect() 16 | def connection_response_code = connection.getResponseCode(); 17 | def connection_response_text=connection.getInputStream().getText() 18 | log.debug "Post Function Log ${connection_response_code} ${baseurl}" 19 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/MLCScopyFieldDuringCreationFromParentToSubTask.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.customfields.option.Option 5 | 6 | /* 7 | Plugin: Multi-Level Cascading Select 8 | Vendor: Sourcesense 9 | https://marketplace.atlassian.com/apps/5008/multi-level-cascading-select?hosting=server&tab=overview 10 | Was used as "Additional issue actions" in Create a sub-task SR post-function 11 | Source article: https://addons.sourcesense.com/display/MCS/Set+the+value+of+an+MLCS+custom+field+using+ScriptRunner 12 | */ 13 | def subComponentCFfromParent = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue.parentObject).find {it.name == 'Sub-Component'} 14 | def parentSubComponentCFValue = (List) issue.parentObject.getCustomFieldValue(subComponentCFfromParent) 15 | if (parentSubComponentCFValue) { 16 | //requires during parent creation only in order to remove from list com.sourcesense.jira.plugin.customfield.option.SpecialOptionFactory$SpecialOption@0 for 'None' from Multi-Level Cascading Select field 17 | def lazyValues = parentSubComponentCFValue.findAll { 18 | it instanceof com.atlassian.jira.issue.customfields.option.LazyLoadedOption 19 | } 20 | def lastChildOption = lazyValues.get(lazyValues.size() - 1) as Option 21 | 22 | def optionsChain = [] 23 | // We store the target option in the array optionsChain, then we add all of its ancestors 24 | optionsChain << lastChildOption 25 | def parentOption = lastChildOption.parentOption 26 | while (parentOption) { 27 | optionsChain << parentOption 28 | parentOption = parentOption.parentOption 29 | } 30 | // We need to reverse the order of the options in the array so that the root-level one is the first 31 | Collections.reverse(optionsChain) 32 | def SubComponentCFfromChild = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 33 | it.name == 'Sub-Component' 34 | } 35 | 36 | //in case sub-task is created via SR post-function 37 | issue.setCustomFieldValue(SubComponentCFfromChild, optionsChain) 38 | 39 | //for regular post-functions 40 | //subComponentCFfromParent.updateValue(null, issue.parentObject, new ModifiedValue(null, optionsChain), new DefaultIssueChangeHolder()) 41 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/MLCScopyFieldFromSubTaskToParent.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.ModifiedValue 5 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 6 | import com.atlassian.jira.issue.util.DefaultIssueChangeHolder 7 | 8 | def subComponentCF = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find {it.name == 'Sub-Component'} 9 | def parentSubComponentCFValue = (ArrayList) issue.getCustomFieldValue(subComponentCF) 10 | 11 | if (parentSubComponentCFValue) { 12 | def lastChildOption = parentSubComponentCFValue.get(parentSubComponentCFValue.size() - 1) 13 | def optionsChain = [] 14 | optionsChain << lastChildOption 15 | def parentOption = lastChildOption.parentOption 16 | while (parentOption) { 17 | optionsChain << parentOption 18 | parentOption = parentOption.parentOption 19 | } 20 | Collections.reverse(optionsChain) 21 | def subComponentCFfromParent = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue.parentObject).find { 22 | it.name == 'Sub-Component' 23 | } 24 | subComponentCFfromParent.updateValue(null, issue.parentObject, new ModifiedValue(null, optionsChain), new DefaultIssueChangeHolder()) 25 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/SetPriority.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.CustomFieldManager 5 | import com.atlassian.jira.issue.fields.CustomField 6 | 7 | CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager() 8 | CustomField storyPointsField = customFieldManager.getCustomFieldObject(10307L) //story point field 9 | 10 | String sp = issue.getCustomFieldValue(storyPointsField) 11 | 12 | if (sp == null || sp.isEmpty()) sp = "0" 13 | 14 | double spD = Double.parseDouble(sp) 15 | 16 | switch (spD) { 17 | case(0): 18 | case(1): 19 | case(2): 20 | case(3): 21 | issue.setPriorityId("5") 22 | break 23 | case(4): 24 | case(5): 25 | case(6): 26 | case(7): 27 | case(8): 28 | issue.setPriorityId("4") 29 | break 30 | } 31 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/StoryCreationForEpic.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 6 | def issueService = ComponentAccessor.issueService 7 | def epicFields = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue) 8 | 9 | //set your values 10 | def customSummary = "custom summary here " 11 | def storyIssueTypeId = 10001 12 | int storyAmount = 2 13 | 14 | def createLinkedStory = { 15 | def storyInputParameters = issueService.newIssueInputParameters() 16 | storyInputParameters 17 | .setSummary(customSummary + epicFields.find {it.name == "Epic Name"}.getValue(issue)) 18 | .setIssueTypeId(storyIssueTypeId as String) 19 | .setReporterId(currentUser.key) 20 | .setProjectId(issue.projectId) 21 | .addCustomFieldValue(epicFields.find {it.name == "Epic Link"}.id, issue.key) 22 | .setSkipScreenCheck(true) 23 | def createValidationResult = issueService.validateCreate(currentUser, storyInputParameters) 24 | if (createValidationResult.valid) issueService.create(currentUser, createValidationResult).issue 25 | else createValidationResult.errorCollection 26 | } 27 | 28 | if (issue.issueType.name == "Epic") storyAmount.times(createLinkedStory) -------------------------------------------------------------------------------- /src/main/jira/post_functions/UpdateFieldBasedOnHistory.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.history.ChangeItemBean 6 | import java.text.SimpleDateFormat 7 | 8 | def issue = issue 9 | def reworkAttempt = 0 10 | List history = ComponentAccessor.getChangeHistoryManager().getChangeItemsForField(issue, "status") 11 | history.each { 12 | if ((it.getFromString().equals("QA") || it.getFromString().equals("Proof ready")) && it.getToString().equals("TS Ordered")) reworkAttempt++ 13 | } 14 | if (reworkAttempt == 0){ 15 | updateDateCfWithHistory(12531L,issue) 16 | } 17 | else{ 18 | updateDateCfWithHistory(12532L,issue) 19 | } 20 | 21 | static void updateDateCfWithHistory(Long cf, def issue) { 22 | 23 | def user = ComponentAccessor.getUserManager().getUserByName("Admin") 24 | Date date = new Date() 25 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MMM/YY") 26 | String stringDate = dateFormat.format(new Date(date.getTime())) 27 | IssueService issueService = ComponentAccessor.getIssueService() 28 | def issueInputParameters = issueService.newIssueInputParameters() 29 | issueInputParameters.addCustomFieldValue(cf, stringDate) 30 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters) 31 | if (validationResult.isValid()) { 32 | issueService.update(user, validationResult) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/UpdateSelectListCF.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | def selectListField = ComponentAccessor.customFieldManager.getCustomFieldObject(10400l) 7 | def optionToSelect = ComponentAccessor.optionsManager.getOptions(selectListField.getRelevantConfig(issue)) 8 | .find {it.value == "CEM"} 9 | def currentValue = issue.getCustomFieldValue(selectListField) 10 | 11 | if (optionToSelect != null && currentValue == null) { 12 | 13 | def issueService = ComponentAccessor.issueService 14 | def issueInputParameters = issueService.newIssueInputParameters() 15 | 16 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 17 | issueInputParameters.addCustomFieldValue(selectListField.idAsLong, optionToSelect.optionId.toString()) 18 | .setSkipScreenCheck(true) 19 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters) 20 | if (validationResult.valid) issueService.update(currentUser, validationResult) 21 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/UpdateUserPickerCF.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.user.ApplicationUser 6 | 7 | def userPickerCF = ComponentAccessor.customFieldManager.getCustomFieldObject(10024l) 8 | def currentValue = userPickerCF.getValue(issue) as ApplicationUser 9 | 10 | if (currentValue == null) { 11 | def issueService = ComponentAccessor.issueService 12 | def issueInputParameters = issueService.newIssueInputParameters() 13 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 14 | issueInputParameters.addCustomFieldValue(userPickerCF.idAsLong, currentUser.key).setSkipScreenCheck(true) 15 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters) 16 | if (validationResult.valid) issueService.update(currentUser, validationResult) 17 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/bamboo/RunBambooBuild.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.bamboo 2 | 3 | def url = new URL('http:// урл бамбу/rest/api/latest/queue/ключ плана') 4 | HttpURLConnection connection = (HttpURLConnection) url.openConnection() 5 | connection.setRequestMethod('POST') 6 | connection.setRequestProperty("Authorization", "Basic ") 7 | connection.getResponseCode() -------------------------------------------------------------------------------- /src/main/jira/post_functions/create_issue/CreateIssueWithLastComment.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.create_issue 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | def issueService = ComponentAccessor.getIssueService() 7 | def issueInputParameters = issueService.newIssueInputParameters() 8 | def applicationUser = ComponentAccessor.getUserManager().getUserByKey(issue.getReporter().getKey()) 9 | 10 | if (applicationUser != null) { 11 | issueInputParameters.setProjectId(issue.getProjectId()) 12 | .setReporterId(applicationUser.getUsername()) 13 | .setPriorityId(issue.getPriority().getId()) 14 | .setSummary(issue.getSummary()) 15 | .setIssueTypeId(issue.getIssueType().getId()) 16 | .setSkipScreenCheck(true) 17 | } 18 | 19 | def commentManager = ComponentAccessor.getCommentManager() 20 | def comment = commentManager.getLastComment(issue) 21 | String lastComment = null 22 | if (comment != null) { 23 | lastComment = comment.getBody() 24 | lastComment = wikiRenderer.render(lastComment, renderContext) 25 | } 26 | 27 | if (lastComment != null) issueInputParameters.setDescription(lastComment) 28 | else issueInputParameters.setDescription(issue.getDescription()) 29 | 30 | IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(applicationUser, issueInputParameters) 31 | if (createValidationResult.isValid()) { 32 | IssueService.IssueResult createResult = issueService.create(applicationUser, createValidationResult) 33 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/create_issue/CreateLinkedIssue.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.create_issue 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.issue.link.IssueLinkTypeManager 6 | import groovy.transform.Field 7 | 8 | @Field final String EXECUTION_USERNAME = "service_users" 9 | @Field final String PROJECT_KEY = "TEST" 10 | @Field final String ISSUE_TYPE_NAME = "Task" 11 | @Field final String LINK_TYPE_NAME = "Relate" 12 | 13 | def issueService = ComponentAccessor.issueService 14 | def projectManager = ComponentAccessor.projectManager 15 | def constantsManager = ComponentAccessor.constantsManager 16 | def issueLinkManager = ComponentAccessor.issueLinkManager 17 | def issueLinkTypeManager = ComponentAccessor.getComponent(IssueLinkTypeManager) 18 | def linkTypes = issueLinkTypeManager.getIssueLinkTypes(false) 19 | 20 | if (issue.issueType.name != "Improvement") return 21 | def conditionFieldVal = getCustomFieldValue("BSS", issue) 22 | if (!conditionFieldVal || !conditionFieldVal.toString().contains("SYNC_ID")) return 23 | 24 | def applicationUser = ComponentAccessor.userManager.getUserByName(EXECUTION_USERNAME) 25 | if (!applicationUser) return 26 | 27 | def issueInputParameters = issueService.newIssueInputParameters() 28 | issueInputParameters.with { 29 | setProjectId(projectManager.getProjectByCurrentKey(PROJECT_KEY).id) 30 | setIssueTypeId(constantsManager.allIssueTypeObjects.find { it.name == ISSUE_TYPE_NAME }.id) 31 | setReporterId(applicationUser.username) 32 | setSummary("${issue.key} ${issue.summary}") 33 | setSkipScreenCheck(true) 34 | } 35 | 36 | def createValidationResult = issueService.validateCreate(applicationUser, issueInputParameters) 37 | if (!createValidationResult.valid) return createValidationResult.errorCollection 38 | def result = issueService.create(applicationUser, createValidationResult) 39 | if (!result.valid) return result.errorCollection 40 | 41 | issueLinkManager.createIssueLink( 42 | issue.id, 43 | result.issue.id, 44 | linkTypes.find { it.name == LINK_TYPE_NAME }.id, 45 | 1, 46 | applicationUser 47 | ) 48 | 49 | static Object getCustomFieldValue(String customFieldName, Issue issue) { 50 | ComponentAccessor.customFieldManager.getCustomFieldObjects(issue) 51 | .find { it.name == customFieldName }?.getValue(issue) 52 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/insight/SetInsightObjectFieldBasedOnReporterRetrievedViaIQL.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.insight 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.type.EventDispatchOption 5 | import com.onresolve.scriptrunner.runner.customisers.PluginModule 6 | import com.onresolve.scriptrunner.runner.customisers.WithPlugin 7 | import com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade 8 | import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade 9 | import com.riadalabs.jira.plugins.insight.services.model.MutableObjectBean 10 | 11 | @WithPlugin("com.riadalabs.jira.plugins.insight") 12 | @PluginModule 13 | IQLFacade iqlFacade 14 | @PluginModule 15 | ObjectFacade objectFacade 16 | 17 | if (issue.issueType.name == "Инцидент") return 18 | 19 | // user with corresponding rights for search and issue update 20 | def executionUser = ComponentAccessor.userManager.getUserByName('Admin') 21 | 22 | // search in Insight 23 | ComponentAccessor.jiraAuthenticationContext.setLoggedInUser(executionUser) 24 | def iql = "objectType = Клиент AND \"Код пользователя\" = ${issue.reporter.name}" 25 | // noinspection GroovyVariableNotAssigned 26 | def client = iqlFacade.findObjects(iql).first() as MutableObjectBean 27 | 28 | // load Insight object, find attribute value and load Insight object 29 | // noinspection GroovyVariableNotAssigned 30 | def companyKey = objectFacade.loadObjectAttributeBean(client.id, "Компания").objectAttributeValueBeans[0].value 31 | def company = objectFacade.loadObjectBean("ITSM-${companyKey}") 32 | def insightCF = ComponentAccessor.customFieldManager.getCustomFieldObject(10267) 33 | 34 | // update issue w/t notification 35 | if (!company || !insightCF) return 36 | def companies = [company] 37 | issue.setCustomFieldValue(insightCF, companies) 38 | ComponentAccessor.issueManager.updateIssue(executionUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false) -------------------------------------------------------------------------------- /src/main/jira/post_functions/insight/SetOrganisationBasedOnReporterInsightValue.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.insight 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.type.EventDispatchOption 5 | import com.atlassian.servicedesk.api.organization.OrganizationService 6 | import com.onresolve.scriptrunner.runner.customisers.PluginModule 7 | import com.onresolve.scriptrunner.runner.customisers.WithPlugin 8 | import com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade 9 | import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade 10 | import com.riadalabs.jira.plugins.insight.services.model.MutableObjectBean 11 | 12 | @WithPlugin("com.riadalabs.jira.plugins.insight") 13 | @PluginModule 14 | IQLFacade iqlFacade 15 | @PluginModule 16 | ObjectFacade objectFacade 17 | 18 | @WithPlugin("com.atlassian.servicedesk") 19 | @PluginModule 20 | OrganizationService organizationService 21 | 22 | // check if reporter is related to a certain company in Insight 23 | def iql = "Пользователь = ${issue.reporter.name}" 24 | // noinspection GroovyVariableNotAssigned 25 | def insightUser = iqlFacade.findObjects(iql).first() as MutableObjectBean 26 | if (!insightUser) return 27 | // noinspection GroovyVariableNotAssigned 28 | def companyId = objectFacade.loadObjectAttributeBean(insightUser.id, "Компания") 29 | .objectAttributeValueBeans.first().referencedObjectBeanId 30 | if (!companyId) return 31 | def companyName = objectFacade.loadObjectBean(companyId).label 32 | if (companyName != "ТЕЛЕ2") return 33 | 34 | def executionUser = ComponentAccessor.userManager.getUserByName("admin") 35 | // noinspection GroovyVariableNotAssigned 36 | def TELE2 = organizationService.getById(executionUser, 120) 37 | def organizationField = ComponentAccessor.customFieldManager.getCustomFieldObject(10002) 38 | def organizationsToAdd = [TELE2] 39 | issue.setCustomFieldValue(organizationField, organizationsToAdd) 40 | ComponentAccessor.issueManager.updateIssue(executionUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false) -------------------------------------------------------------------------------- /src/main/jira/post_functions/insight/legacy_SetInsightObjectFieldBasedOnReporterRetrievedViaIQL.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.insight 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.event.type.EventDispatchOption 5 | 6 | if (issue.issueType.name == "Инцидент") return 7 | 8 | // user with corresponding rights for search and issue update 9 | def executionUser = ComponentAccessor.userManager.getUserByName('Admin') 10 | 11 | // search in Insight 12 | ComponentAccessor.jiraAuthenticationContext.setLoggedInUser(executionUser) 13 | def iql = "objectType = Клиент AND \"Код пользователя\" = ${issue.reporter.name}" 14 | def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(ComponentAccessor.getPluginAccessor() 15 | .getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade")) 16 | def client = iqlFacade.findObjectsByIQL(iql) as List 17 | 18 | // load Insight object, find attribute value and load Insight object 19 | def objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(ComponentAccessor.getPluginAccessor() 20 | .getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade")) 21 | def companyKey = objectFacade.loadObjectAttributeBean(client[0].id, "Компания").objectAttributeValueBeans[0].value 22 | def company = objectFacade.loadObjectBean("ITSM-${companyKey}") 23 | def insightCF = ComponentAccessor.customFieldManager.getCustomFieldObject(10267) 24 | 25 | // update issue w/t notification 26 | if (!company || !insightCF) return 27 | def companies = [company] 28 | issue.setCustomFieldValue(insightCF, companies) 29 | ComponentAccessor.issueManager.updateIssue(executionUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false) -------------------------------------------------------------------------------- /src/main/jira/post_functions/set_field_based_on/DateFieldValues.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.set_field_based_on 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import java.text.SimpleDateFormat 6 | 7 | log.info "Working with ${issue.key}" 8 | def customFields = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue) 9 | 10 | // values for checking 11 | def plannedStartDateVal = customFields.find { it.name == "Planned Start date"}?.getValue(issue) 12 | def plannedEndDateVal = customFields.find { it.name == "Planned End Date"}?.getValue(issue) 13 | def plannedEffortVal = customFields.find { it.name == "Planned Effort"}?.getValue(issue) 14 | 15 | // fields to update 16 | def baselineStartDate = customFields.find { it.name == "Baseline start date"} 17 | def baselineEndDate = customFields.find { it.name == "Baseline end date"} 18 | def baselineEffort = customFields.find { it.name == "Baseline Effort"} 19 | 20 | def executionUser = ComponentAccessor.userManager.getUserByName("tech_user") 21 | def issueService = ComponentAccessor.issueService 22 | def input = issueService.newIssueInputParameters() 23 | input.with { 24 | setSkipScreenCheck(true) 25 | if (plannedStartDateVal) addCustomFieldValue(baselineStartDate.id, 26 | new SimpleDateFormat("dd/MMM/yy").format(plannedStartDateVal)) 27 | if (plannedStartDateVal) addCustomFieldValue(baselineEndDate.id, 28 | new SimpleDateFormat("dd/MMM/yy").format(plannedEndDateVal)) 29 | if (plannedEffortVal) addCustomFieldValue(baselineEffort.id, plannedEffortVal as String) 30 | } 31 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(executionUser, 32 | issue.id, input) 33 | if (validationResult.valid) issueService.update(executionUser, validationResult).errorCollection 34 | else log.info validationResult.errorCollection as String -------------------------------------------------------------------------------- /src/main/jira/post_functions/set_field_based_on/ResolutionDate.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.set_field_based_on 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import java.text.SimpleDateFormat 6 | 7 | def resolutionDate = issue.resolutionDate 8 | if (!resolutionDate) return 9 | def actualEndDate = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 10 | it.name == "Actual End Date" } 11 | def executionUser = ComponentAccessor.userManager.getUserByName("tech_user") 12 | def issueService = ComponentAccessor.issueService 13 | def input = issueService.newIssueInputParameters() 14 | input.addCustomFieldValue(actualEndDate.id, 15 | new SimpleDateFormat("dd/MMM/yy").format(resolutionDate)).setSkipScreenCheck(true) 16 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(executionUser, 17 | issue.id, input) 18 | log.info "Validation result: ${validationResult.valid}" 19 | if (validationResult.valid) issueService.update(executionUser, validationResult).errorCollection 20 | else log.info validationResult.errorCollection.toString() -------------------------------------------------------------------------------- /src/main/jira/post_functions/sub_task_creation_based_on/SingleSelectListValue0.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.sub_task_creation_based_on 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | // for testing in script console 6 | def issue = ComponentAccessor.issueManager.getIssueObject("ITSDTEST-2") 7 | 8 | def subTaskId = 10101 9 | def issueService = ComponentAccessor.issueService 10 | def subTaskManager = ComponentAccessor.subTaskManager 11 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 12 | def teamRoleValue = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 13 | it.id == "customfield_16920" 14 | }.getValue(issue).toString() 15 | 16 | def general = ["Jira", "Active Directory (Network Account)", "Office", "OpenAir", "LMS", "Concur"] 17 | def finance = general.collect() << "NetSuite" 18 | def engineering = general.collect() << "Wiki" 19 | 20 | def createSubTask = { summary -> 21 | def subTaskInputParameters = issueService.newIssueInputParameters() 22 | subTaskInputParameters 23 | .setSummary(summary as String) 24 | .setIssueTypeId(subTaskId as String) 25 | .setReporterId(user.key) 26 | .setProjectId(issue.projectId) 27 | .setPriorityId(issue.priority.id) 28 | .setSkipScreenCheck(true) 29 | def createValidationResult = issueService.validateSubTaskCreate(user, issue.id, subTaskInputParameters) 30 | if (createValidationResult.valid) { 31 | def subTask = issueService.create(user, createValidationResult).issue 32 | subTaskManager.createSubTaskIssueLink(issue, subTask, user) 33 | } 34 | else createValidationResult.errorCollection 35 | } 36 | 37 | switch (teamRoleValue) { 38 | case "General": 39 | general.each{ createSubTask(it)} 40 | break 41 | case "Finance": 42 | finance.each{createSubTask(it)} 43 | break 44 | case "Engineering": 45 | engineering.each{createSubTask(it)} 46 | break 47 | default: 48 | break 49 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/sub_task_creation_based_on/SingleSelectListValue1.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.sub_task_creation_based_on 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | if (issue.issueType.subTask) return 6 | def customFieldManager = ComponentAccessor.customFieldManager 7 | def selectListVal = customFieldManager.getCustomFieldObjects(issue) 8 | .find { it.name == "Car" }?.getValue(issue) as String 9 | if (!selectListVal) return 10 | 11 | def subTaskIssueTypeId = ComponentAccessor.constantsManager.allIssueTypeObjects 12 | .find { it.name == "Sub-Task" }.id 13 | def executionUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 14 | def issueService = ComponentAccessor.issueService 15 | def newIssueInputParameters = issueService.newIssueInputParameters() 16 | newIssueInputParameters.with { 17 | setSkipScreenCheck(true) 18 | setIssueTypeId(subTaskIssueTypeId as String) 19 | setProjectId(issue.projectId) 20 | setSummary("${selectListVal}: ${issue.summary}") 21 | setReporterId(executionUser.name) 22 | setPriorityId(issue.priority.id) 23 | } 24 | def createValidationResult = issueService.validateSubTaskCreate(executionUser, issue.id, newIssueInputParameters) 25 | if (createValidationResult.valid) { 26 | def subTaskIssue = issueService.create(executionUser, createValidationResult).issue 27 | ComponentAccessor.subTaskManager.createSubTaskIssueLink(issue, subTaskIssue, executionUser) 28 | } else createValidationResult.errorCollection -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/ChangeEpicStatusInProgress.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor; 5 | import com.atlassian.jira.issue.CustomFieldManager 6 | import com.atlassian.jira.issue.Issue 7 | import com.atlassian.jira.issue.IssueInputParameters; 8 | import com.atlassian.jira.issue.IssueManager; 9 | import com.atlassian.jira.issue.MutableIssue; 10 | import com.atlassian.jira.issue.fields.CustomField; 11 | import com.atlassian.jira.user.ApplicationUser; 12 | 13 | String user = "tech_user"; 14 | ApplicationUser applicationUser = ComponentAccessor.getUserManager().getUserByKey(user); 15 | 16 | CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager(); 17 | CustomField epicLink = customFieldManager.getCustomFieldObject(10200L); 18 | String epicKey = issue.getCustomFieldValue(epicLink).toString(); 19 | 20 | IssueManager issueManager = ComponentAccessor.getIssueManager(); 21 | MutableIssue issueEpic = issueManager.getIssueObject(epicKey); 22 | 23 | if (issueEpic != null) { 24 | 25 | String originalEpicStatus = issueEpic.getStatus().getSimpleStatus().getName(); 26 | 27 | if (originalEpicStatus.equals("To Do")) { 28 | transitEpic(issueEpic, applicationUser); 29 | } 30 | } 31 | 32 | void transitEpic(Issue issue, ApplicationUser applicationUser) { 33 | IssueService issueService = ComponentAccessor.getIssueService(); 34 | IssueInputParameters issueInputParameters = issueService.newIssueInputParameters(); 35 | 36 | if (issue.getAssignee() == null) issueInputParameters.setAssigneeId(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser().getKey()); 37 | 38 | IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(applicationUser, issue.getId(), 51, issueInputParameters); 39 | if (transitionValidationResult.isValid()) { 40 | IssueService.IssueResult transitionResult = issueService.transition(applicationUser, transitionValidationResult); 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/ChangeFeatureStatusInProgress.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | import com.atlassian.jira.issue.IssueInputParameters 7 | import com.atlassian.jira.issue.link.IssueLink 8 | import com.atlassian.jira.issue.link.IssueLinkManager 9 | import com.atlassian.jira.user.ApplicationUser 10 | 11 | String user = "tech_user"; 12 | ApplicationUser applicationUser = ComponentAccessor.getUserManager().getUserByKey(user); 13 | 14 | //get link to Feature 15 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager(); 16 | List epicLinks = issueLinkManager.getInwardLinks(issue.getId()); 17 | 18 | if (epicLinks != null && epicLinks.size() > 0) { 19 | Issue issueFeature = null; 20 | epicLinks.each { 21 | issueFeature = it.getSourceObject(); 22 | if (issueFeature.getIssueType().getName().equals("Roadmap Feature") && issueFeature.getKey().contains("INFRA-")) { 23 | transitFeature(issueFeature, applicationUser); 24 | } 25 | } 26 | } 27 | 28 | static Collection transitFeature(Issue issueFeature, ApplicationUser applicationUser) { 29 | IssueService issueService = ComponentAccessor.getIssueService(); 30 | IssueInputParameters issueInputParameters = issueService.newIssueInputParameters(); 31 | 32 | if (issueFeature.getAssignee() == null) issueInputParameters.setAssigneeId(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser().getKey()); 33 | 34 | IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(applicationUser, issueFeature.getId(), 51, issueInputParameters); 35 | if (transitionValidationResult.isValid()) { 36 | IssueService.IssueResult transitionResult = issueService.transition(applicationUser, transitionValidationResult); 37 | return transitionResult.errorCollection.errorMessages; 38 | } 39 | return null; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/FastTrackTransitionAnIssueConfition.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def customFieldManager = ComponentAccessor.customFieldManager 6 | def externalTeamToEngage = customFieldManager.getCustomFieldObject("customfield_10232") //Select List (multiple choices) Default value: ? 7 | def dependencyType = customFieldManager.getCustomFieldObject("customfield_10508") //Select List (multiple choices) Default value: ? 8 | def sourceSystem = customFieldManager.getCustomFieldObject("customfield_10503") // Select List (single choice) Default value: ? 9 | def middleware = customFieldManager.getCustomFieldObject("customfield_10505") // Select List (single choice) Default value: ? 10 | def targetSystem = customFieldManager.getCustomFieldObject("customfield_10504") // Select List (single choice) Default value: ? 11 | 12 | def userStory = issue 13 | def externalTeamToEngageValues = userStory.getCustomFieldValue(externalTeamToEngage) as String 14 | def dependencyTypeValues = userStory.getCustomFieldValue(dependencyType) as String 15 | def sourceSystemValue = userStory.getCustomFieldValue(sourceSystem) as String 16 | def middlewareValue = userStory.getCustomFieldValue(middleware) as String 17 | def targetSystemValue = userStory.getCustomFieldValue(targetSystem) as String 18 | 19 | def defaultValue = String.valueOf((char) 8212) 20 | 21 | (externalTeamToEngageValues && externalTeamToEngageValues.indexOf(defaultValue) == -1) || 22 | (dependencyTypeValues && dependencyTypeValues.indexOf(defaultValue) == -1) || 23 | (sourceSystemValue && sourceSystemValue.indexOf(defaultValue) == -1) || 24 | (middlewareValue && middlewareValue.indexOf(defaultValue) == -1) || 25 | (targetSystemValue && targetSystemValue.indexOf(defaultValue) == -1) -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitCascadeParentsWhenFirstSubtaskInprogress.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.workflow.TransitionOptions.Builder 6 | import org.apache.log4j.Logger 7 | import org.apache.log4j.Level 8 | 9 | def log = Logger.getLogger("check") 10 | log.setLevel(Level.DEBUG) 11 | log.debug issue.getStatus().name.toString() 12 | def checkFirst = 0 13 | def parentIssue 14 | def transitionId 15 | def issueLinkManager = ComponentAccessor.getIssueLinkManager() 16 | if (issue.isSubTask()){ 17 | parentIssue= issue.getParentObject() 18 | if (parentIssue.getStatus().getStatusCategory().name.equals('New')){ 19 | transitIssue(271,parentIssue) 20 | log.debug "task transited" 21 | } 22 | else return 23 | } 24 | else{ 25 | if (issue.getProjectObject().name!='Master (HOF)' && issue.getProjectObject().name!='EpicsWithoutIssues (HOF)'){ 26 | def epic = issue.getCustomFieldValue(ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('Epic Link')) 27 | if (epic.getStatus().getStatusCategory().name.equals('New')){ 28 | transitIssue(271,epic) 29 | log.debug "epic transited" 30 | def inlink = issueLinkManager.getInwardLinks(epic.getId()).find {link-> link.getIssueLinkType().getId()==10504} 31 | if (inlink!=null) { 32 | def feature = inlink.getSourceObject() 33 | if (feature.getStatus().getStatusCategory().name.equals('New')){ 34 | transitIssue(271,feature) 35 | log.debug "feature transited" 36 | } 37 | } 38 | } 39 | } 40 | else log.debug "epic or feature" 41 | } 42 | 43 | def transitIssue (int transitionId, Issue parentIssue){ 44 | def applicationUser = ComponentAccessor.getUserManager().getUserByKey("tech_user") 45 | def issueService = ComponentAccessor.getIssueService(); 46 | def issueInputParameters = issueService.newIssueInputParameters(); 47 | def builder = new Builder() 48 | def transopt = builder.skipConditions().skipValidators().skipPermissions() 49 | def transitionValidationResult = issueService.validateTransition(applicationUser, parentIssue.getId(), transitionId, issueInputParameters,transopt.build()) 50 | if (transitionValidationResult.isValid()) { 51 | def transitionResult = issueService.transition(applicationUser, transitionValidationResult) 52 | log.debug transitionResult.getErrorCollection() 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitEpicBasedOnStoryStatus.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | 7 | //for testing in script console 8 | def issue = ComponentAccessor.issueManager.getIssueObject("PFT-65") 9 | def summaryCheck = "Prioritization Assessment" 10 | def epicTransitionId = 101 11 | def epic = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 12 | it.name == "Epic Link" 13 | }?.getValue(issue) as Issue 14 | 15 | def transitionIssue = { Issue localIssue -> 16 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 17 | def issueService = ComponentAccessor.issueService 18 | def issueInputParameters = issueService.newIssueInputParameters() 19 | issueInputParameters.setSkipScreenCheck(true) 20 | IssueService.TransitionValidationResult transitionValidationResult = 21 | issueService.validateTransition(currentUser, localIssue.id, epicTransitionId, issueInputParameters) 22 | if (transitionValidationResult.valid) issueService.transition(currentUser, transitionValidationResult) 23 | else transitionValidationResult.errorCollection 24 | } 25 | 26 | def condition = epic && epic.status.name != "Ready" && issue.issueType.name == "Story" && 27 | issue.summary.toLowerCase().contains(summaryCheck.toLowerCase()) 28 | if (condition) transitionIssue(epic) 29 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitEpicBasedOnStorySubTasks.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | 7 | //for testing in script console 8 | def issue = ComponentAccessor.issueManager.getIssueObject("PFT-65") 9 | def epicTransitionId = 91 10 | def summaryCheck = "Prioritization Assessment" 11 | def epic = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue.parentObject).find { 12 | it.name == "Epic Link" 13 | }?.getValue(issue.parentObject) as Issue 14 | 15 | def transitionIssue = { Issue localIssue -> 16 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 17 | def issueService = ComponentAccessor.issueService 18 | def issueInputParameters = issueService.newIssueInputParameters() 19 | issueInputParameters.setSkipScreenCheck(true) 20 | IssueService.TransitionValidationResult transitionValidationResult = 21 | issueService.validateTransition(currentUser, localIssue.id, epicTransitionId, issueInputParameters) 22 | if (transitionValidationResult.valid) issueService.transition(currentUser, transitionValidationResult) 23 | else transitionValidationResult.errorCollection 24 | } 25 | 26 | def condition = epic && issue.parentObject.issueType.name == "Story" && epic.status.name != "Priority Review" && 27 | issue.parentObject.summary.toLowerCase().contains(summaryCheck.toLowerCase()) && 28 | issue.parentObject.subTaskObjects.every { it.status.name == "Done" } 29 | if (condition) transitionIssue(epic) -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitIssueBasedOnFieldValues.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | //DTO Approval field (string) 7 | def dto = ComponentAccessor.customFieldManager.getCustomFieldObject(10965l) 8 | def isDtoApproved = Boolean.parseBoolean(dto.getValueFromIssue(issue)) 9 | 10 | //Technical Support Approval (String) 11 | def ts = ComponentAccessor.customFieldManager.getCustomFieldObject(10966l) 12 | def isTsApproved = Boolean.parseBoolean(ts.getValueFromIssue(issue)) 13 | 14 | if (isDtoApproved && isTsApproved) { 15 | def issueService = ComponentAccessor.issueService 16 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 17 | def param = issueService.newIssueInputParameters() 18 | IssueService.TransitionValidationResult transitionValidationResult = issueService. 19 | validateTransition(currentUser, issue.getId(), 51, param) 20 | if (transitionValidationResult.isValid()) issueService.transition(currentUser, transitionValidationResult) 21 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitIssueIfAnotherTransitionDone.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | if (issue.get("customfield_10964")==1){ 7 | IssueService issueService = ComponentAccessor.getIssueService() 8 | def iIParameters = issueService.newIssueInputParameters(); 9 | IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(currentUser, issue.getId(), 51, iIParameters) 10 | if (transitionValidationResult.isValid()) { 11 | IssueService.IssueResult transitionResult = issueService.transition(currentUser, transitionValidationResult) 12 | } 13 | } 14 | else { 15 | def issueService = ComponentAccessor.getIssueService() 16 | def issueInputParameters = issueService.newIssueInputParameters() 17 | issueInputParameters.addCustomFieldValue(10964L,"2") 18 | def validationResult = issueService.validateUpdate(currentUser, issue.getId(), issueInputParameters) 19 | if (validationResult.isValid()) { 20 | issueService.update(currentUser, validationResult).hasWarnings() 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitLinkedIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | def issuesForTransition = ComponentAccessor.issueLinkManager.getInwardLinks(issue.id).findAll { 7 | it.issueLinkType.name == "Tests" && it.sourceObject.status.name == "Done" 8 | }.collect { it.sourceObject } 9 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 10 | def issueService = ComponentAccessor.issueService 11 | def issueInputParameters = issueService.newIssueInputParameters() 12 | if (issuesForTransition) { 13 | issuesForTransition.each { 14 | IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(user, 15 | it.id, 161, issueInputParameters) 16 | if (transitionValidationResult.isValid()) { 17 | issueService.transition(user, transitionValidationResult) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitParentIssueOfSubtaskInProgress.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.IssueInputParameters 6 | import com.atlassian.jira.issue.MutableIssue 7 | import com.atlassian.jira.issue.link.IssueLinkManager 8 | import com.atlassian.jira.user.ApplicationUser 9 | 10 | String user = "tech_user"; 11 | ApplicationUser applicationUser = ComponentAccessor.getUserManager().getUserByKey(user); 12 | 13 | //take parent issue instead of sub-task and transit it 14 | MutableIssue parentIssue; 15 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager(); 16 | issueLinkManager.getInwardLinks(issue.getId()).each { 17 | if (it.getIssueLinkType().getId() == 10100) { 18 | parentIssue = (MutableIssue) it.getSourceObject(); 19 | return true; 20 | } 21 | } 22 | 23 | //transit parent issue 24 | if (parentIssue != null) { 25 | IssueService issueService = ComponentAccessor.getIssueService(); 26 | IssueInputParameters issueInputParameters = issueService.newIssueInputParameters(); 27 | if (parentIssue.getAssignee() == null) issueInputParameters.setAssigneeId(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser().getKey()); 28 | 29 | String parentIssueType = parentIssue.getIssueType().getName(); 30 | int transitionId; 31 | 32 | switch (parentIssueType) { 33 | case "Bug": 34 | case "Task": 35 | case "Technical Debt": 36 | case "Story": 37 | transitionId = 51; 38 | break; 39 | case "Production Issue": 40 | transitionId = 11; 41 | break; 42 | } 43 | 44 | IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(applicationUser, parentIssue.getId(), transitionId, issueInputParameters); 45 | if (transitionValidationResult.isValid()) { 46 | IssueService.IssueResult transitionResult = issueService.transition(applicationUser, transitionValidationResult); 47 | return transitionResult.getErrorCollection().each {}; 48 | } 49 | } 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitParentIssueWhenSubTaskIsInprogress.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | 7 | def issue = ComponentAccessor.issueManager.getIssueObject("PFT-65") //for testing in script console only 8 | 9 | def storyTransitionId = 21 10 | def summaryCheckA = "-Data Ingestion" 11 | def summaryCheckB = "-Content Story" 12 | def parentIssue = issue?.parentObject 13 | 14 | def transitionIssue = { Issue localIssue -> 15 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 16 | def issueService = ComponentAccessor.issueService 17 | def issueInputParameters = issueService.newIssueInputParameters() 18 | issueInputParameters.setSkipScreenCheck(true) 19 | IssueService.TransitionValidationResult transitionValidationResult = 20 | issueService.validateTransition(currentUser, localIssue.id, storyTransitionId, issueInputParameters) 21 | if (transitionValidationResult.valid) issueService.transition(currentUser, transitionValidationResult) 22 | else transitionValidationResult.errorCollection 23 | } 24 | 25 | if (parentIssue && parentIssue.issueType.name == "Story" && parentIssue.status.name != "In Progress" && 26 | (parentIssue.summary.toLowerCase().contains(summaryCheckA.toLowerCase()) || 27 | parentIssue.summary.toLowerCase().contains(summaryCheckB.toLowerCase()))) { 28 | transitionIssue(parentIssue) 29 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitPortfolioParentIfChildInStatus.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.web.bean.PagerFilter 6 | import com.atlassian.jira.bc.issue.search.SearchService 7 | import com.atlassian.jira.workflow.TransitionOptions.Builder 8 | 9 | String feature = (ComponentAccessor.customFieldManager.getCustomFieldObject(10201L).getValue(issue)).getKey() 10 | List statuses = ["Delivered Waiting Approval","Discontinued","Approved","Outdated"] 11 | def applicationUser = ComponentAccessor.getUserManager().getUserByKey("auto") 12 | List issuesUnderFeature = new ArrayList<>() 13 | def searchService = ComponentAccessor.getComponentOfType(SearchService.class) 14 | def final SearchService.ParseResult parseResult = searchService.parseQuery(applicationUser, "'Parent Link' in ($feature)"); 15 | if (parseResult.isValid()) { 16 | def results = searchService.search(applicationUser, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) 17 | issuesUnderFeature = results.getIssues() 18 | def value = 0 19 | issuesUnderFeature.each{epic-> 20 | if (statuses.contains(epic.getStatus().name))value++ 21 | } 22 | if (value==issuesUnderFeature.size()){ 23 | def featureIssue = ComponentAccessor.getIssueManager().getIssueObject(feature) 24 | def transitId = 31 25 | def issueService = ComponentAccessor.getIssueService() 26 | def builder = new Builder() 27 | def transopt = builder.skipConditions().skipValidators().skipPermissions() 28 | def transitionValidationResult = issueService.validateTransition(applicationUser, featureIssue.getId(), transitId, issueService.newIssueInputParameters(),transopt.build()) 29 | if (transitionValidationResult.isValid()) issueService.transition(applicationUser, transitionValidationResult) 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitSubTaskFromSubTask.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | 7 | def parentIssue = issue.parentObject 8 | def issueService = ComponentAccessor.issueService 9 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 10 | parentIssue.subTaskObjects.findAll { it.status.name == "Released" }?.each { issue -> 11 | issue = issue as Issue 12 | def issueInputParameters = issueService.newIssueInputParameters() 13 | IssueService.TransitionValidationResult transitionValidationResult = 14 | issueService.validateTransition(currentUser, issue.id, 321, issueInputParameters) 15 | if (transitionValidationResult.isValid()) { 16 | issueService.transition(currentUser, transitionValidationResult) 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/jira/post_functions/transitions/TransitSubtaskDependingOnOtherSubtaks.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.transitions 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import com.atlassian.jira.issue.Issue 6 | 7 | def issue = ComponentAccessor.issueManager.getIssueObject("PFT-65") //for testing in script console only 8 | 9 | def readyTransitionId = 31 10 | def conditionSubTaskSummaries = ["Splunk Trending Queries and Supporting Queries", "Create Rule in Dev splunk ES", 11 | "Content Peer Review", "mitre mapping", "Create Rule in Prod for Test", 12 | "soc qa"].collect { it.toLowerCase() } 13 | def conditionStatus = "Done" 14 | def transitionSubTaskSummaries = ["Soc approval"].collect { it.toLowerCase() } 15 | def assigneeUsername = "user" 16 | def scriptExecutor = "user" 17 | 18 | def conditionSubTasks = issue.parentObject.subTaskObjects.findAll { 19 | it.summary.toLowerCase() in conditionSubTaskSummaries 20 | } 21 | def transitionSubTasks = issue.parentObject.subTaskObjects.findAll { 22 | it.summary.toLowerCase() in transitionSubTaskSummaries 23 | } 24 | def transitionCondition = conditionSubTasks.every { 25 | it.summary.toLowerCase() in conditionSubTaskSummaries && 26 | it.status.name == conditionStatus && conditionSubTaskSummaries.size() == conditionSubTasks.size() 27 | } 28 | 29 | def transitionIssue = { Issue localIssue -> 30 | ComponentAccessor.jiraAuthenticationContext.setLoggedInUser(ComponentAccessor.userManager.getUserByKey(scriptExecutor)) 31 | def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 32 | def issueService = ComponentAccessor.issueService 33 | def issueInputParameters = issueService.newIssueInputParameters() 34 | issueInputParameters.setSkipScreenCheck(true) 35 | issueInputParameters.setAssigneeId(assigneeUsername) 36 | IssueService.TransitionValidationResult transitionValidationResult = 37 | issueService.validateTransition(currentUser, localIssue.id, readyTransitionId, issueInputParameters) 38 | if (transitionValidationResult.valid) issueService.transition(currentUser, transitionValidationResult) 39 | else transitionValidationResult.errorCollection 40 | } 41 | if (transitionCondition && transitionSubTasks) transitionSubTasks.each { transitionIssue(it) } -------------------------------------------------------------------------------- /src/main/jira/post_functions/watchers/AddWatchersBasedOnCustomFieldValue.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.watchers 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def watcherManager = ComponentAccessor.watcherManager 6 | def userManager = ComponentAccessor.userManager 7 | def cfManager = ComponentAccessor.customFieldManager 8 | def cf = cfManager.getCustomFieldObject("customfield_ID") 9 | def value = issue.getCustomFieldValue(cf) 10 | 11 | def watchUsers = { usernames -> 12 | usernames.each { 13 | def user = userManager.getUserByName(it.toString()) 14 | watcherManager.startWatching(user, issue) 15 | } 16 | } 17 | if (value.toString() == "Value"){ 18 | def users = ["username","comma","separated"] 19 | watchUsers(users) 20 | } 21 | -------------------------------------------------------------------------------- /src/main/jira/post_functions/watchers/HardcodedListOfWatchers.groovy: -------------------------------------------------------------------------------- 1 | package jira.post_functions.watchers 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def actualWatchers = [] 6 | if (issue.projectObject.key == "SD") { 7 | def watchers = [:] 8 | watchers["Резервное копирование"] = ["VProhorov"] 9 | watchers["JiraServiceDesk"] = ["azvonkov"] 10 | watchers["StaaS"] = ["VProhorov"] 11 | watchers["VMware"] = ["VProhorov"] 12 | watchers["Openstack"] = ["VProhorov"] 13 | watchers["ТехноСерв Диск"] = ["VProhorov"] 14 | watchers["Инфраструктура"] = ["VProhorov"] 15 | watchers["ОХ(хранилище)"] = ["VProhorov"] 16 | def serviceValue = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue) 17 | .find { it.name == "Сервис клиента" }?.getValue(issue) as String 18 | if (!serviceValue) return 19 | actualWatchers = watchers.find { serviceValue.contains(it.key as String) }.value as List 20 | } else if (issue.projectObject.key == "IS") { 21 | actualWatchers = ["VProhorov", "MRaspertov"] 22 | } 23 | if (!actualWatchers || actualWatchers.isEmpty()) return 24 | def userManger = ComponentAccessor.userManager 25 | def watcherManager = ComponentAccessor.watcherManager 26 | actualWatchers.each { username -> 27 | watcherManager.startWatching(userManger.getUserByName(username as String), issue) 28 | } -------------------------------------------------------------------------------- /src/main/jira/script_console/AddToProjectRole.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.security.roles.ProjectRoleManager 5 | import com.atlassian.jira.security.roles.RoleActorFactory 6 | import com.atlassian.jira.security.roles.ProjectRoleActor 7 | 8 | def projectManager = ComponentAccessor.projectManager 9 | def projectRoleManager = ComponentAccessor.getComponentOfType(ProjectRoleManager) 10 | def roleActorFactory = ComponentAccessor.getComponentOfType(RoleActorFactory) 11 | 12 | def projectKeys = ["PKEY1", "PKEY2", "PKEY3"] 13 | def groupNames = ["group1", "group2"] 14 | def roleName = "role1" 15 | 16 | def role = projectRoleManager.getProjectRole(roleName) 17 | 18 | projectKeys.each { projectKey -> 19 | def project = projectManager.getProjectByCurrentKey(projectKey) 20 | def projectRoleActors = projectRoleManager.getProjectRoleActors(role, project) 21 | def newRoleActors = groupNames.collect{ groupName -> 22 | roleActorFactory.createRoleActor(null, role.id, project.id, ProjectRoleActor.GROUP_ROLE_ACTOR_TYPE, groupName) 23 | } 24 | projectRoleActors = projectRoleActors.addRoleActors(newRoleActors) 25 | projectRoleManager.updateProjectRoleActors(projectRoleActors) 26 | } 27 | -------------------------------------------------------------------------------- /src/main/jira/script_console/AttachmentLinks.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.attachment.Attachment 5 | 6 | def issue = ComponentAccessor.issueManager.getIssueByCurrentKey("HAUFE-893") 7 | def baseurl = ComponentAccessor.applicationProperties.getString("jira.baseurl") 8 | 9 | issue.attachments.collect { Attachment attachment -> 10 | baseurl + "/secure/attachment/" + attachment.id + "/" + attachment.filename 11 | } -------------------------------------------------------------------------------- /src/main/jira/script_console/ChangeBoardFilter.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.greenhopper.manager.rapidview.RapidViewManager 4 | import com.atlassian.greenhopper.model.rapid.RapidView 5 | import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean 6 | 7 | //shoud be tested on JIRA 7 8 | long BOARD_ID = 0L //board that was bugged 9 | long FILTER_Id = 0L //new filter for that board 10 | 11 | @JiraAgileBean 12 | RapidViewManager rapidViewManager 13 | 14 | RapidView rapidView = rapidViewManager.get(BOARD_ID).get() 15 | rapidViewManager.update(new RapidView.RapidViewBuilder(rapidView).savedFilterId(FILTER_Id).build()) -------------------------------------------------------------------------------- /src/main/jira/script_console/ChangeReporterAssigneeFromFile.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.bc.issue.search.SearchService 5 | import com.atlassian.jira.component.ComponentAccessor 6 | import com.atlassian.jira.issue.Issue 7 | import com.atlassian.jira.issue.IssueInputParameters 8 | import com.atlassian.jira.issue.search.SearchResults 9 | import com.atlassian.jira.user.ApplicationUser 10 | import com.atlassian.jira.web.bean.PagerFilter 11 | 12 | String user = "tech_user" 13 | String jqlQuery = "issuekey = VM-1" 14 | String filePath = "/opt/jira_data/scriptrunner/mapping.txt" 15 | 16 | def issueService = ComponentAccessor.getIssueService() 17 | def searchService = ComponentAccessor.getComponentOfType(SearchService.class) 18 | def userManager = ComponentAccessor.getUserManager() 19 | 20 | ApplicationUser applicationUser = userManager.getUserByKey(user) 21 | 22 | //get data from file 23 | def mapping = new HashMap() 24 | def sourceFile = new File(filePath) 25 | sourceFile.eachLine {line -> 26 | String[] formatedArr = line.replaceAll("\"", "").split(",") 27 | mapping.put(formatedArr[0], formatedArr[1]) 28 | } 29 | 30 | //get issues from JQL query 31 | final SearchService.ParseResult parseResult = searchService.parseQuery(applicationUser, jqlQuery) 32 | List issues = new ArrayList<>() 33 | if (parseResult.isValid()) { 34 | final SearchResults results = searchService.search(applicationUser, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) 35 | issues = results.getIssues() 36 | } 37 | 38 | //issues.each {issue -> 39 | def issue = issues.get(0) 40 | IssueInputParameters issueInputParameters = issueService.newIssueInputParameters() 41 | def assignee = (ApplicationUser) issue.getAssignee() 42 | def reporter = (ApplicationUser) issue.getReporter() 43 | 44 | if (assignee != null && mapping.containsKey(assignee.getKey())) issueInputParameters.setAssigneeId(mapping.get(assignee.getKey())) 45 | if (reporter != null && mapping.containsKey(reporter.getKey())) issueInputParameters.setReporterId(mapping.get(reporter.getKey())) 46 | 47 | IssueService.UpdateValidationResult validationResult = issueService.validateUpdate(applicationUser, issue.getId(), issueInputParameters) 48 | if (validationResult.isValid()) { 49 | issueService.update(applicationUser, validationResult) 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/jira/script_console/DeactivateUsers.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.crowd.embedded.impl.ImmutableUser 4 | import com.atlassian.jira.bc.user.UserService 5 | import com.atlassian.jira.component.ComponentAccessor 6 | import com.atlassian.jira.user.ApplicationUsers 7 | 8 | //Add usernames here 9 | def users = [] 10 | 11 | def userManager = ComponentAccessor.userManager 12 | def userService = ComponentAccessor.getComponent(UserService) 13 | def jiraAthenticationContext = ComponentAccessor.jiraAuthenticationContext 14 | 15 | //You have to change the value "admin" for your admin user. 16 | def admin = userManager.getUserByName("admin") 17 | jiraAthenticationContext.setLoggedInUser(admin) 18 | 19 | users.each{ username -> 20 | def userToDisable = userManager.getUserByName(username) 21 | def userToDisableFromDirectory = ApplicationUsers.toDirectoryUser(userToDisable) 22 | def updateUser = ApplicationUsers.from(ImmutableUser.newUser(userToDisableFromDirectory).active(true).toUser()) 23 | def updateUserValidationResult = userService.validateUpdateUser(updateUser) 24 | if (updateUserValidationResult.isValid()) { 25 | userService.updateUser(updateUserValidationResult) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/jira/script_console/MakeEpicFieldRequired.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | // Make Epic Link Field Required Without SR Behaviours 6 | def fieldLayoutManager = ComponentAccessor.fieldLayoutManager 7 | 8 | def projectId = ComponentAccessor.projectManager.getProjectObjByName("Test Epic Link").id 9 | def issueTypeId = ComponentAccessor.constantsManager.allIssueTypeObjects.find { it.name == "Task"}.id 10 | def fieldLayout = fieldLayoutManager.getFieldLayout(projectId, issueTypeId) 11 | 12 | def editableFieldLayout = fieldLayoutManager.getEditableFieldLayout(fieldLayout.id) 13 | def epicLinkField = ComponentAccessor.customFieldManager.customFieldObjects.find { it.name == "Epic Link" } 14 | def fieldLayoutItem = editableFieldLayout.getFieldLayoutItem(epicLinkField) 15 | 16 | editableFieldLayout.makeRequired(fieldLayoutItem) 17 | fieldLayoutManager.storeEditableFieldLayout(editableFieldLayout) -------------------------------------------------------------------------------- /src/main/jira/script_console/PermissionSchemeBulkAssignment.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def permissionSchemeName = "Cхема Read-Only для закрытых проектов" 6 | def permissionsSchemeManager = ComponentAccessor.permissionSchemeManager 7 | def permissionScheme = permissionsSchemeManager.getSchemeObject(permissionSchemeName) 8 | 9 | ComponentAccessor.projectManager.projectObjects.each { 10 | if (it.name.contains("АРХИВ")) { 11 | //Too many PermissionScheme schemes found for Project 12 | permissionsSchemeManager.removeSchemesFromProject(it) 13 | permissionsSchemeManager.addSchemeToProject(it, permissionScheme) 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/jira/script_console/RenameActiveWorkflow.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.bc.JiraServiceContextImpl; 5 | import com.atlassian.jira.bc.workflow.WorkflowService; 6 | import com.atlassian.jira.user.ApplicationUser; 7 | import com.atlassian.jira.workflow.JiraWorkflow; 8 | 9 | /** 10 | * After running the script, go to workflow scheme with affected workflow and updated scheme by adding any change 11 | * (assign any issue type to any workflow in the scheme and revert the change => Publish). This will trigger changes 12 | * for old issues, which use affected workflow. Otherwise, workflow buttons will disappear from issue view on all issues, 13 | * that use affected workflow and had been created prior to workflow renaming. 14 | */ 15 | 16 | String oldName="Workflow 1.1"; 17 | String newName = "Workflow 1"; 18 | 19 | ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(); 20 | JiraServiceContextImpl jiraServiceContextImpl = new JiraServiceContextImpl(currentUser); 21 | WorkflowService ws = ComponentAccessor.getComponent(WorkflowService.class); 22 | JiraWorkflow workflow = ws.getWorkflow(jiraServiceContextImpl, oldName); 23 | ws.updateWorkflowNameAndDescription(jiraServiceContextImpl, workflow, newName, workflow.getDescription()); 24 | -------------------------------------------------------------------------------- /src/main/jira/script_console/RenameUsernamesToEmailPrefix.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.crowd.embedded.impl.ImmutableUser 4 | import com.atlassian.jira.user.ApplicationUsers 5 | import com.atlassian.jira.user.ApplicationUser 6 | import com.atlassian.jira.component.ComponentAccessor 7 | import com.atlassian.jira.user.DelegatingApplicationUser 8 | 9 | //can be used for bulk user renaming in JIRA internal dir 10 | 11 | def userManager = ComponentAccessor.userManager 12 | def users = userManager.users 13 | 14 | users.each { ApplicationUser user -> 15 | def email = user.emailAddress 16 | if (email) { 17 | def newName = email.substring(0, email.indexOf("@")).toLowerCase() 18 | if (newName != user.name.toLowerCase()) { 19 | log.warn "New name: ${newName}" 20 | log.warn "Old name: ${user.name}" 21 | ImmutableUser.Builder builder = ImmutableUser.newUser(ApplicationUsers.toDirectoryUser(user)) 22 | builder.name(newName) 23 | builder.toUser() 24 | userManager.updateUser(new DelegatingApplicationUser(user.id, user.key, builder.toUser())) 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/jira/script_console/RenameUsers.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.crowd.embedded.impl.ImmutableUser 4 | import com.atlassian.jira.user.ApplicationUsers 5 | import com.atlassian.jira.user.ApplicationUser 6 | import com.atlassian.jira.user.util.UserUtil 7 | import com.atlassian.jira.user.util.UserManager 8 | import com.atlassian.jira.component.ComponentAccessor 9 | import com.atlassian.jira.user.DelegatingApplicationUser 10 | 11 | //can be used for bulk user renaming in JIRA internal dir 12 | UserUtil userUtil = ComponentAccessor.getUserUtil() 13 | List users = (List) userUtil.getUsers() 14 | 15 | for (ApplicationUser user : users) 16 | { 17 | if (user.getUsername().contains("@some.com")) { 18 | ImmutableUser.Builder builder = ImmutableUser.newUser(ApplicationUsers.toDirectoryUser(user)) 19 | builder.name(user.getUsername().substring(0, user.getUsername().length() - 9)) 20 | builder.toUser() 21 | UserManager userManager = ComponentAccessor.getUserManager() 22 | userManager.updateUser(new DelegatingApplicationUser(user.getId(), user.getKey(), builder.toUser())) 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/jira/script_console/UpdateIssueSystemFields.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.issue.MutableIssue; 4 | import com.atlassian.jira.component.ComponentAccessor 5 | import java.sql.Timestamp 6 | 7 | /* 8 | MutableIssue is facade for an issue's GenericValue. 9 | After calling any 'setter' method, you will need to call store() to persist the change to the database. 10 | Note that this is a 'shallow' store - only fields directly part of the issue (in the database schema) are persisted. 11 | Treat this like operation similar to DB updates. Such update avoid all business JIRA logic, events, etc. Method store() is for JIRA internal usage only. 12 | However, we can use it in order to avoid direct DB updates in cases when we understand what we do!! 13 | 14 | */ 15 | 16 | MutableIssue issue = ComponentAccessor.getIssueManager().getIssueObject("ID-16"); //issue key 17 | Timestamp time = new Timestamp(2052, 3, 2, 7, 15, 22, 0); 18 | 19 | //Timestamp(int year, int month, int date, int hour, int minute, int second, int nano) 20 | // be careful with months(first is 0) and hours (may depend on JVM settings, etc) 21 | 22 | issue.setCreated(time); 23 | issue.setResolutionDate(time); 24 | issue.setUpdated(time); 25 | 26 | issue.store(); 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/jira/script_console/UpdatesOfCFbyUser.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.issue.changehistory.ChangeHistoryItem 6 | import com.atlassian.jira.issue.changehistory.ChangeHistoryManager 7 | import com.atlassian.jira.user.ApplicationUser 8 | 9 | String affectedUser = "user"; 10 | String affectedField = "Team"; 11 | 12 | List users = new ArrayList<>(); 13 | users.add(affectedUser); 14 | 15 | ApplicationUser user = ComponentAccessor.getUserManager().getUserByKey(affectedUser); 16 | ChangeHistoryManager changeHistoryManager = ComponentAccessor.getChangeHistoryManager(); 17 | List issuesUpdatedByUser = (List) changeHistoryManager.findUserHistory(user, users, 10000); 18 | Set resultIssues = new HashSet<>(); 19 | 20 | issuesUpdatedByUser.each { issue -> 21 | List cih = changeHistoryManager.getAllChangeItems(issue); 22 | cih.each { 23 | if (it.getUserKey().equals(affectedUser) && it.getField().equals(affectedField)) { 24 | resultIssues.add(issue.getKey()); 25 | return; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/main/jira/script_console/UsersRemovalFromProjectRole.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.security.roles.ProjectRoleActors 5 | import com.atlassian.jira.security.roles.ProjectRoleManager 6 | import com.atlassian.jira.security.roles.RoleActor 7 | 8 | def projectRoleManager = ComponentAccessor.getComponentOfType(ProjectRoleManager.class) 9 | def project = ComponentAccessor.projectManager.getProjectByCurrentKey("RAD") 10 | def projectRole = projectRoleManager.getProjectRole("Verificators") 11 | def projectRoleActors = projectRoleManager.getProjectRoleActors(projectRole, project) 12 | def userRoleActorsForRemoval = projectRoleActors.roleActors.findAll { RoleActor roleActor -> 13 | roleActor.type == "atlassian-user-role-actor" 14 | } 15 | def updatedActors = projectRoleActors.removeRoleActors(userRoleActorsForRemoval) 16 | projectRoleManager.updateProjectRoleActors(updatedActors as ProjectRoleActors) -------------------------------------------------------------------------------- /src/main/jira/script_console/bulk_issue_creation/EpicsWithoutIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.bulk_issue_creation 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.component.ComponentAccessor 5 | 6 | int amountOfEpics = 1500 7 | def issueTypeID = "10000" // Epic 8 | def projectId = 10306 // Test 9 | def priorityId = "4" 10 | 11 | def issueService = ComponentAccessor.issueService 12 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser 13 | 14 | amountOfEpics.times { 15 | def issueInputParameters = issueService.newIssueInputParameters() 16 | issueInputParameters 17 | .setProjectId(projectId) 18 | .setSummary("Epic Test") 19 | .setDescription("test desc") 20 | .setIssueTypeId(issueTypeID) 21 | .setPriorityId(priorityId) 22 | .setReporterId(user.username) 23 | .addCustomFieldValue(10103, "test") 24 | 25 | IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(user, issueInputParameters) 26 | log.error("issue input parameters: " + issueInputParameters.getActionParameters()) 27 | if (createValidationResult.isValid()) 28 | { 29 | IssueService.IssueResult createResult = issueService.create(user, createValidationResult) 30 | if (!createResult.isValid()) log.error("Error while creating the issue.") 31 | } 32 | else createValidationResult.errorCollection.errorMessages 33 | } -------------------------------------------------------------------------------- /src/main/jira/script_console/bulk_issue_creation/ProjectsWithIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.bulk_issue_creation 2 | 3 | import com.atlassian.jira.bc.issue.IssueService 4 | import com.atlassian.jira.bc.project.ProjectService 5 | import com.atlassian.jira.component.ComponentAccessor 6 | import com.atlassian.jira.bc.project.ProjectCreationData.Builder 7 | 8 | final int amountOfProjects = 5 9 | final String prefixKey = "TEST" 10 | final String projectType = "business" 11 | final int amountOfProjectIssues = 2000 12 | final String issueType = "Story" 13 | final String priority = "Medium" 14 | 15 | def executionUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser 16 | def projectService = ComponentAccessor.getComponent(ProjectService) 17 | def issueService = ComponentAccessor.issueService 18 | def issueTypeId = ComponentAccessor.constantsManager.allIssueTypeObjects.find { it.name == issueType }.id 19 | def priorityId = ComponentAccessor.constantsManager.priorities.find { it.name == priority }.id 20 | 21 | amountOfProjects.times { int counter -> 22 | def builder = new Builder() 23 | builder.with { 24 | withKey(prefixKey + counter as String) 25 | withName(prefixKey + counter as String) 26 | withLead(executionUser) 27 | withDescription(prefixKey + counter as String) 28 | withType(projectType) 29 | } 30 | def projectData = builder.build() 31 | def projectValidationResult = projectService.validateCreateProject(executionUser, projectData) 32 | if (projectValidationResult.valid) { 33 | def project = projectService.createProject(projectValidationResult) 34 | amountOfProjectIssues.times { 35 | def issueInputParameters = issueService.newIssueInputParameters() 36 | issueInputParameters.with { 37 | setProjectId(project.id) 38 | setSummary("Test") 39 | setDescription("Test") 40 | setIssueTypeId(issueTypeId) 41 | setReporterId(executionUser.username) 42 | setPriorityId(priorityId) 43 | } 44 | IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(executionUser, issueInputParameters) 45 | if (createValidationResult.valid) issueService.create(executionUser, createValidationResult) 46 | else createValidationResult.errorCollection.errorMessages 47 | } 48 | } else projectValidationResult.errorCollection.errorMessages 49 | } -------------------------------------------------------------------------------- /src/main/jira/script_console/cleanup/DeleteInactiveIssueTypeSchemes.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.cleanup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.fields.config.FieldConfigScheme; 5 | import com.atlassian.jira.issue.fields.config.manager.IssueTypeSchemeManager; 6 | 7 | IssueTypeSchemeManager issueTypeSchemeManager = ComponentAccessor.getIssueTypeSchemeManager(); 8 | List fieldConfigSchemes = issueTypeSchemeManager.getAllSchemes(); 9 | StringBuilder report = new StringBuilder(); 10 | 11 | int i = 0; 12 | 13 | fieldConfigSchemes.each { 14 | 15 | if (!it.getName().equals("Default Issue Type Scheme") && it.getAssociatedProjectObjects().size() == 0) { 16 | report.append(it.getName()); 17 | report.append(" | "); 18 | i++; 19 | issueTypeSchemeManager.deleteScheme(it); 20 | } 21 | } 22 | return "All:"+ i + " " + report.toString(); -------------------------------------------------------------------------------- /src/main/jira/script_console/cleanup/DeleteInactiveIssueTypeScreenSchemes.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.cleanup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenScheme; 5 | import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenSchemeManager; 6 | 7 | IssueTypeScreenSchemeManager issueTypeScreenSchemeManager = ComponentAccessor.getIssueTypeScreenSchemeManager(); 8 | StringBuilder report = new StringBuilder(); 9 | 10 | Collection schemes = issueTypeScreenSchemeManager.getIssueTypeScreenSchemes(); 11 | schemes.each { 12 | if (issueTypeScreenSchemeManager.getProjects(it).size() == 0) { 13 | report.append(it.getName()); 14 | report.append(" | "); 15 | issueTypeScreenSchemeManager.removeIssueTypeSchemeEntities(it); 16 | issueTypeScreenSchemeManager.removeIssueTypeScreenScheme(it); 17 | } 18 | } 19 | 20 | return report.toString(); 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/jira/script_console/cleanup/DeleteInactiveScreenSchemes.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.cleanup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.fields.screen.FieldScreenScheme; 5 | import com.atlassian.jira.issue.fields.screen.FieldScreenSchemeManager; 6 | import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenSchemeManager; 7 | 8 | FieldScreenSchemeManager fieldScreenSchemeManager = ComponentAccessor.getComponent(FieldScreenSchemeManager.class); 9 | IssueTypeScreenSchemeManager issueTypeScreenSchemeManager = ComponentAccessor.getIssueTypeScreenSchemeManager(); 10 | 11 | StringBuilder report = new StringBuilder(); 12 | Collection fieldScreenSchemes = fieldScreenSchemeManager.getFieldScreenSchemes(); 13 | 14 | fieldScreenSchemes.each { 15 | if (issueTypeScreenSchemeManager.getIssueTypeScreenSchemes(it).size() == 0) { 16 | report.append(it.getName()); 17 | report.append(" | "); 18 | fieldScreenSchemeManager.removeFieldSchemeItems(it); 19 | fieldScreenSchemeManager.removeFieldScreenScheme(it); 20 | } 21 | } 22 | return report.toString(); -------------------------------------------------------------------------------- /src/main/jira/script_console/cleanup/DeleteInactiveScreens.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.cleanup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.fields.screen.FieldScreen; 5 | import com.atlassian.jira.issue.fields.screen.FieldScreenManager; 6 | import com.atlassian.jira.issue.fields.screen.FieldScreenSchemeManager; 7 | import com.atlassian.jira.workflow.JiraWorkflow; 8 | import com.atlassian.jira.workflow.WorkflowManager; 9 | 10 | FieldScreenManager fieldScreenManager = ComponentAccessor.getFieldScreenManager(); 11 | WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager(); 12 | FieldScreenSchemeManager fieldScreenSchemeManager = ComponentAccessor.getComponent(FieldScreenSchemeManager.class); 13 | 14 | Collection fieldScreens = fieldScreenManager.getFieldScreens(); 15 | Collection workflows = workflowManager.getWorkflows(); 16 | 17 | StringBuilder report = new StringBuilder(); 18 | int index = 0; 19 | 20 | fieldScreens.each {fieldScreen -> 21 | boolean hasScreanScheme = false; 22 | boolean isWorkflowScreen = false; 23 | 24 | for (int i = 0; i < workflows.size(); i++) { 25 | if (workflows.getAt(i).getActionsForScreen(fieldScreen).size() > 0) { 26 | isWorkflowScreen = true; 27 | break; 28 | } 29 | } 30 | 31 | if (fieldScreenSchemeManager.getFieldScreenSchemes(fieldScreen).size() > 0) { 32 | hasScreanScheme = true; 33 | } 34 | 35 | if (!hasScreanScheme && !isWorkflowScreen) { 36 | report.append(fieldScreen.getName()); 37 | report.append(" | "); 38 | index++; 39 | 40 | fieldScreen.getTabs().each { 41 | fieldScreenManager.removeFieldScreenLayoutItems(it); 42 | } 43 | fieldScreenManager.removeFieldScreenTabs(fieldScreen); 44 | fieldScreenManager.removeFieldScreen(fieldScreen.getId()); 45 | } 46 | } 47 | return "All: " + index + report.toString(); -------------------------------------------------------------------------------- /src/main/jira/script_console/cleanup/DeleteInactiveWorkflowSchemes.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.cleanup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def schemeManager = ComponentAccessor.workflowSchemeManager 6 | 7 | def sb = new StringBuffer() 8 | 9 | schemeManager.schemeObjects.each { 10 | try{ 11 | if(schemeManager.getProjectsUsing(schemeManager.getWorkflowSchemeObj(it.id)).size() == 0) { 12 | sb.append("Deleting workflow scheme: ${it.name}\n") 13 | schemeManager.deleteScheme(it.id) 14 | } 15 | } 16 | catch(Exception e) { 17 | //noop 18 | sb.append("Error: " + e + "\n"); 19 | } 20 | } 21 | 22 | return sb.toString() 23 | -------------------------------------------------------------------------------- /src/main/jira/script_console/cleanup/DeleteInactiveWorkflows.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.cleanup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.workflow.JiraWorkflow; 5 | import com.atlassian.jira.workflow.WorkflowManager; 6 | import com.atlassian.jira.workflow.WorkflowSchemeManager; 7 | 8 | WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager(); 9 | WorkflowSchemeManager workflowSchemeManager = ComponentAccessor.getWorkflowSchemeManager(); 10 | StringBuilder report = new StringBuilder(); 11 | 12 | Collection workflows = workflowManager.getWorkflows(); 13 | workflows.removeAll(workflowManager.getActiveWorkflows()); 14 | 15 | workflows.each { 16 | if (workflowSchemeManager.getSchemesForWorkflow(it).size() == 0) { 17 | report.append(it.getName()); 18 | report.append(" | ") 19 | workflowManager.deleteWorkflow(it); 20 | } 21 | } 22 | return report.toString(); 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/main/jira/script_console/reports/CustomFieldReport.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.reports 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.fields.CustomField; 5 | 6 | List cfs = new ArrayList<>(); 7 | for (CustomField cf : ComponentAccessor.getCustomFieldManager().getCustomFieldObjects()) 8 | { 9 | cfs.add("ID: " + cf.getIdAsLong() + " NAME: " + cf.getName() + " TYPE: " + cf.getCustomFieldType().getName()); 10 | } 11 | return cfs.each{}; 12 | -------------------------------------------------------------------------------- /src/main/jira/script_console/reports/IssueTypeReport.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.reports 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.issuetype.IssueType; 5 | List issueTypes = new ArrayList<>(); 6 | for (IssueType issueType : ComponentAccessor.getConstantsManager().getAllIssueTypeObjects()) 7 | { 8 | issueTypes.add("ID: " + issueType.getId() + " NAME: " + issueType.getName()); 9 | } 10 | return issueTypes.each{}; -------------------------------------------------------------------------------- /src/main/jira/script_console/reports/WorkflowStatusReport.groovy: -------------------------------------------------------------------------------- 1 | package jira.script_console.reports 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | import com.atlassian.jira.issue.status.Status; 5 | List statuses = new ArrayList<>(); 6 | for (Status status : ComponentAccessor.getConstantsManager().getStatuses()) 7 | { 8 | statuses.add("ID: " + status.getId() + " NAME: " + status.getName() + " CATEGORY: " + status.getStatusCategory().getName() + " COLOR: " + status.getStatusCategory().getColorName()); 9 | } 10 | return statuses.each{}; -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/CalculateCFsValues.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | //Script Location: Scripted Field 6 | //Searcher: Number Searcher 7 | //Template: Number Field 8 | 9 | def customFieldManager = ComponentAccessor.getCustomFieldManager() 10 | def storyPoints = customFieldManager.getCustomFieldObject(10307L) 11 | def businessValue = customFieldManager.getCustomFieldObject(10300L) 12 | 13 | String sp = issue.getCustomFieldValue(storyPoints) 14 | String bv = issue.getCustomFieldValue(businessValue) 15 | 16 | if (sp == null || sp.isEmpty()) sp = "0" 17 | def spValue = Double.parseDouble(sp) 18 | 19 | if (bv == null || bv.isEmpty()) return null 20 | def bvValue = Double.parseDouble(bv) 21 | 22 | if (spValue >= 0 && spValue <= 3 && bvValue == 3) return 1 23 | else if (spValue >= 0 && spValue <= 3 && bvValue >= 1 && bvValue <= 2) return 3 24 | else if (spValue > 3 && bvValue == 3) return 2 25 | else if (spValue > 3 && bvValue >= 1 && bvValue <= 2) return 4 26 | else return null -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/CalculateCFsValuestp.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | //Script Location: Scripted Field 6 | //Searcher: Number Searcher 7 | //Template: Number Field 8 | 9 | def customFieldManager = ComponentAccessor.getCustomFieldManager() 10 | def storyPoints = customFieldManager.getCustomFieldObject(10307L) 11 | def businessValue = customFieldManager.getCustomFieldObject(10300L) 12 | 13 | String sp = issue.getCustomFieldValue(storyPoints) 14 | String bv = issue.getCustomFieldValue(businessValue) 15 | 16 | if (sp == null || sp.isEmpty()) sp = "0" 17 | def spValue = Double.parseDouble(sp) 18 | 19 | if (bv == null || bv.isEmpty()) return null 20 | def bvValue = Double.parseDouble(bv) 21 | 22 | if (spValue >= 0 && spValue <= 3 && bvValue == 3) return 1 23 | else if (spValue >= 0 && spValue <= 3 && bvValue >= 1 && bvValue <= 2) return 3 24 | else if (spValue > 3 && bvValue == 3) return 2 25 | else if (spValue > 3 && bvValue >= 1 && bvValue <= 2) return 4 26 | else return null -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/CookieRestCallScriptedFieldForSignaturePluginHTML.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import groovy.xml.MarkupBuilder 4 | import groovyx.net.http.HTTPBuilder 5 | import static groovyx.net.http.Method.GET 6 | import static groovyx.net.http.Method.POST 7 | import static groovyx.net.http.ContentType.JSON 8 | import com.atlassian.jira.component.ComponentAccessor 9 | import java.text.SimpleDateFormat 10 | 11 | def sessionRequest = new HTTPBuilder("https://jira.example.com/rest/auth/1/session") 12 | def authResponse = sessionRequest.request(POST, JSON) { request -> 13 | body = [username: 'auto', password: 'secret'] 14 | request.setHeader("Content-Type", "application/json") 15 | } 16 | def signatureRequest = new HTTPBuilder("https://jira.example.com/rest/electronic-signature/1.0/signature/${issue.key}") 17 | def signatures = signatureRequest.request(GET, JSON) { request -> 18 | request.setHeader("Content-Type", "application/json") 19 | request.setHeader("Cookie", "JSESSIONID=${authResponse.get('session').get('value')}") 20 | } 21 | def sdf = new SimpleDateFormat("dd MMM yyyy HH:mm") 22 | def writer = null 23 | if (signatures) { 24 | writer = new StringWriter() 25 | def builder = new MarkupBuilder(writer) 26 | builder.table(class: "aui") { 27 | thead { 28 | tr { 29 | th("User") 30 | th("Date") 31 | th("From Status") 32 | th("To Status") 33 | } 34 | } 35 | tbody { 36 | signatures.each { signature -> 37 | tr { 38 | td("${ComponentAccessor.userManager.getUserByKey(signature.get("userKey")).displayName}") 39 | td("${sdf.format(signature.get("date"))}") 40 | td("${signature.get("fromStatus")}") 41 | td("${signature.get("toStatus")}") 42 | } 43 | } 44 | } 45 | } 46 | writer.toString() 47 | } -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/CookieRestCallScriptedFieldForSignaturePluginWikiMarkup.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import groovyx.net.http.HTTPBuilder 4 | import static groovyx.net.http.Method.GET 5 | import static groovyx.net.http.Method.POST 6 | import static groovyx.net.http.ContentType.JSON 7 | import com.atlassian.jira.component.ComponentAccessor 8 | import java.text.SimpleDateFormat 9 | 10 | def f = new SimpleDateFormat("dd MMM yyyy HH:mm") 11 | def authRequest = new HTTPBuilder("https://jira.example.com/rest/auth/1/session") 12 | def authResponse = authRequest.request(POST,JSON) { req -> 13 | body = [username: 'auto', password: 'secret'] 14 | req.setHeader("Content-Type", "application/json") 15 | } 16 | def signaturesRequest = new HTTPBuilder("https://jira.example.com/rest/electronic-signature/1.0/signature/${issue.key}") 17 | def signatures = signaturesRequest.request(GET,JSON) { req -> 18 | req.setHeader("Content-Type", "application/json") 19 | req.setHeader("Cookie", "JSESSIONID="+authResponse.get("session").get("value").toString()) 20 | } 21 | if (signatures) { 22 | // wiki markup style was used in JMCF (not scriptrunner scripted fields) 23 | String output = "||User||Date||From Status||To Status||\n" 24 | signatures.each { 25 | output += "|" + ComponentAccessor.userManager.getUserByKey(it.get("userKey").toString()).getDisplayName() + "|" 26 | output += f.format(new Date((it.get("date")))).toString() + "|" 27 | output += it.get("fromStatus").toString() + "|" 28 | output += it.get("toStatus").toString() + "|\n" 29 | } 30 | output 31 | } 32 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/FinishedEpicsUnderFeature.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.MutableIssue 5 | 6 | def issue = issue as MutableIssue 7 | if (issue.issueType.name == "Roadmap Feature") { 8 | def linker = ComponentAccessor.issueLinkManager 9 | return linker.getOutwardLinks(issue.id).findAll{ it.destinationObject.issueType.name == "Epic" && 10 | it.destinationObject.status.statusCategory.name == "Complete"}.size() 11 | } -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/FixVersionOrStatusChangeWithinCurrentDate.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | /* 3 | Not finished yet 4 | */ 5 | import com.atlassian.jira.component.ComponentAccessor 6 | import java.time.LocalDate 7 | 8 | def issue = ComponentAccessor.issueManager.getIssueObject("TZZ-3") 9 | LocalDate now = LocalDate.now() 10 | def historyManager = ComponentAccessor.changeHistoryManager 11 | def wasFixedVersionChanged = historyManager.getChangeItemsForField(issue, "Fix Version") 12 | .any {it.created.toLocalDateTime().toLocalDate().isEqual(now)} 13 | 14 | def statusChanges = historyManager.getChangeItemsForField(issue, "status") 15 | .findAll{it.created.toLocalDateTime().toLocalDate().isEqual(now)} 16 | 17 | def wasStatusChanged = statusChanges.any {it.fromString.toLowerCase() in ["open", "blocked", "stopped", "reopened", "in progress"] && 18 | it.toString.toLowerCase() in ["verified", "closed", "resolved"]} 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/LastAttachmentDate.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def AttachmentM = ComponentAccessor.getAttachmentManager() 6 | def Attachmelts = AttachmentM.getAttachments(issue) 7 | def AttachmentSize = Attachmelts.size() 8 | if (Attachmelts != null && AttachmentSize > 0){ 9 | def AttachmentLast = Attachmelts[0].getCreated() 10 | 11 | for (def i=1;iAttachmentLast) 14 | AttachmentLast = Attachmelts[i].getCreated() 15 | } 16 | return AttachmentLast 17 | } 18 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/LastComment.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.fields.renderer.IssueRenderContext 5 | 6 | def commentManager = ComponentAccessor.commentManager 7 | def comment = commentManager.getLastComment(issue) 8 | def lastComment = null 9 | if (comment) { 10 | lastComment = comment.body 11 | def wikiRenderer = ComponentAccessor.rendererManager.getRendererForType("atlassian-wiki-renderer") 12 | def renderContext = new IssueRenderContext(issue) 13 | lastComment = wikiRenderer.render(lastComment, renderContext) 14 | } 15 | return lastComment -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/MaxValOfDateFieldInEpicIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import java.sql.Timestamp 5 | 6 | if (issue.issueType.name != "Epic") return 7 | def epicIssues = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id) 8 | .findAll { it.issueLinkType.name == "Epic-Story Link" } 9 | *.destinationObject 10 | if (!epicIssues || epicIssues.empty) return 11 | def actualEndDate = ComponentAccessor.customFieldManager.customFieldObjects 12 | .find { it.name == "Actual End Date" } 13 | def allEndDateVals = epicIssues 14 | .findAll { actualEndDate.getValue(it) != null } 15 | .collect { actualEndDate.getValue(it) as Timestamp} 16 | if (!allEndDateVals || allEndDateVals.empty) return 17 | Collections.sort(allEndDateVals) 18 | return allEndDateVals.last() -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/MinValOfDateFieldInEpicIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import java.sql.Timestamp 5 | 6 | if (issue.issueType.name != "Epic") return 7 | def epicIssues = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id) 8 | .findAll { it.issueLinkType.name == "Epic-Story Link" } 9 | *.destinationObject 10 | if (!epicIssues || epicIssues.empty) return 11 | def actualStartDate = ComponentAccessor.customFieldManager.customFieldObjects 12 | .find { it.name == "Actual Start Date" } 13 | def allStartDateVals = epicIssues 14 | .findAll { actualStartDate.getValue(it) != null } 15 | .collect { actualStartDate.getValue(it) as Timestamp} 16 | if (!allStartDateVals || allStartDateVals.empty) return 17 | Collections.sort(allStartDateVals) 18 | return allStartDateVals.first() -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/NotFinishedEpicsUnderFeature.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.MutableIssue 5 | 6 | def issue = issue as MutableIssue 7 | if (issue.issueType.name == "Roadmap Feature") { 8 | def linker = ComponentAccessor.issueLinkManager 9 | return linker.getOutwardLinks(issue.id).findAll{ it.destinationObject.issueType.name == "Epic" && 10 | it.destinationObject.status.statusCategory.name in ["New", "In Progress"]}.size() 11 | } -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/OrigEstMinusRemEst.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | // Template: Duration (time-tracking) 3 | def origEst = issue.originalEstimate 4 | def remEst = issue.estimate 5 | if (!origEst) return 6 | return (origEst - remEst) //3600 -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/ParentIssueKeyForEpic.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.issue.link.IssueLink 6 | import com.atlassian.jira.issue.link.IssueLinkManager 7 | 8 | if (issue.getIssueType().getName().equals("Epic")) { 9 | 10 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() 11 | List epicLinks = issueLinkManager.getInwardLinks(issue.getId()) 12 | 13 | if (epicLinks != null && epicLinks.size() > 0) { 14 | Issue issueFeature = epicLinks[0].getSourceObject() 15 | return issueFeature.getKey() 16 | } else return null 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/ParentSubtaskFilter.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | def parentIssue = issue.getParentObject(); 4 | def parentIssueKey, issueKey; 5 | 6 | if (parentIssue != null) { 7 | parentIssueKey = parentIssue.getKey(); 8 | return parentIssueKey; 9 | } 10 | else { 11 | issueKey = issue.getKey(); 12 | return issueKey; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/PlannedStoryPointsinChildren.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | 5 | int SP = 0; 6 | linkManager = ComponentAccessor.getIssueLinkManager(); 7 | customFieldManager = ComponentAccessor.getCustomFieldManager(); 8 | storyPointsField = customFieldManager.getCustomFieldObject(10002L); 9 | 10 | if (issue.getIssueType().getName() == "Epic") { 11 | 12 | def storiesCollection = linkManager.getOutwardLinks(issue.id); 13 | def storyIssue; 14 | if (storiesCollection!=null) { 15 | for (stories in storiesCollection.iterator()){ 16 | storyIssue = stories.getDestinationObject(); 17 | if (storyIssue.getStatus().getName().equals("Done")) 18 | SP += storyPointsField.getValue(storyIssue); 19 | } 20 | } 21 | } 22 | 23 | /* FIELD DESCRIPTION 24 | 40 | 41 | */ -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/SumOfChildStoryPointsOnFeature.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor; 4 | 5 | def issueLinkManager = ComponentAccessor.getIssueLinkManager() 6 | def totalSP = 0.0 7 | enableCache = {-> false} 8 | 9 | 10 | log.debug("Issue ${issue}") 11 | issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->; 12 | 13 | 14 | if ((issueLink.issueLinkType.name == "Epic-Story Link")) { 15 | customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points") 16 | def SP = issueLink.destinationObject.getCustomFieldValue(customField) as Double ?: 0.0 17 | log.debug("SP value ${SP}") 18 | totalSP += SP 19 | }} 20 | 21 | return totalSP as Double 22 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/SumOfDateFieldInEpicIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | if (issue.issueType.name != "Epic") return 6 | def epicIssues = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id) 7 | .findAll { it.issueLinkType.name == "Epic-Story Link" } 8 | *.destinationObject 9 | if (!epicIssues || epicIssues.empty) return 10 | def actualEffortCF = ComponentAccessor.customFieldManager.customFieldObjects 11 | .find { it.name == "Actual Effort" } 12 | 13 | def allActualEffortVals = epicIssues 14 | .findAll { actualEffortCF.getValue(it) != null } 15 | .collect { actualEffortCF.getValue(it) } 16 | 17 | if (!allActualEffortVals || allActualEffortVals.empty) return 18 | allActualEffortVals.sum() -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/SumOrigEstInEpicIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | if (issue.issueType.name != "Epic") return 6 | def epicIssues = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id) 7 | .findAll { it.issueLinkType.name == "Epic-Story Link" } 8 | *.destinationObject 9 | if (epicIssues.empty) return 10 | return epicIssues 11 | .findAll { it.originalEstimate != null } 12 | .collect { it.originalEstimate }.sum() -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/SunLoggedWorkInEpicsIssuesAndSubTask.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def issuesRelatedToEpic = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id) 6 | .findAll { it.issueLinkType.name == "Epic-Story Link" } 7 | *.destinationObject 8 | def epicSubTasks = issue.subTaskObjects 9 | if (!epicSubTasks.empty) issuesRelatedToEpic += epicSubTasks 10 | def loggedWork = issuesRelatedToEpic.findResults { it.timeSpent }?.sum() -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/counters/GroupPickerChanges.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields.counters 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def changeHistoryManager = ComponentAccessor.changeHistoryManager 6 | def groupHistory = changeHistoryManager.getChangeItemsForField(issue, "Группа исполнителей") 7 | return groupHistory?.size() -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/counters/ReopenCounter.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields.counters 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def changeHistoryManager = ComponentAccessor.changeHistoryManager 6 | def statusChangeItemBean = changeHistoryManager.getChangeItemsForField(issue, "status") 7 | int reopenedCount = statusChangeItemBean.findAll { it.toString == "Reopened" }?.size() 8 | int undoReopenCount = statusChangeItemBean.findAll { it.toString == "Undo Reopen" }?.size() 9 | return reopenedCount - undoReopenCount 10 | -------------------------------------------------------------------------------- /src/main/jira/scripted_fields/counters/StatusChanges.groovy: -------------------------------------------------------------------------------- 1 | package jira.scripted_fields.counters 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | def changeHistoryManager = ComponentAccessor.changeHistoryManager 6 | def statusHistory = changeHistoryManager.getChangeItemsForField(issue, "status") 7 | return statusHistory.findAll { it.fromString in ["Завершено", "Закрыто"] }?.size() -------------------------------------------------------------------------------- /src/main/jira/startup/MakeEpicFieldRequiredInCertainFieldConfigurations.groovy: -------------------------------------------------------------------------------- 1 | package jira.startup 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | /** 6 | * Make Epic Link Field Required Without SR Behaviours 7 | * Field Configurations Ids: jira_base_url/secure/admin/ViewFieldLayouts.jspa 8 | * Does not work with Default Field Configuration 9 | */ 10 | 11 | def affectedFieldLayoutIds = [10400, 10500] 12 | 13 | def epicLinkField = ComponentAccessor.customFieldManager.customFieldObjects.find { it.name == "Epic Link" } 14 | def fieldLayoutManager = ComponentAccessor.fieldLayoutManager 15 | 16 | affectedFieldLayoutIds.each { fieldLayoutId -> 17 | def editableFieldLayout = fieldLayoutManager.getEditableFieldLayout(fieldLayoutId) 18 | def fieldLayoutItem = editableFieldLayout.getFieldLayoutItem(epicLinkField) 19 | if (editableFieldLayout && fieldLayoutItem) { 20 | editableFieldLayout.makeRequired(fieldLayoutItem) 21 | fieldLayoutManager.storeEditableFieldLayout(editableFieldLayout) 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/jira/validators/CheckSubtaskStatusWithCertainSummary.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.opensymphony.workflow.InvalidInputException 4 | 5 | def conditionSummary = "Code review for ${issue.key}" 6 | def isNotAllowed = issue.subTaskObjects?.any { it.summary == conditionSummary && it.status.name != "Closed" } 7 | if (isNotAllowed) throw new InvalidInputException("Code review subtask should be closed before transition to QA.") -------------------------------------------------------------------------------- /src/main/jira/validators/CommentRequiredDuringTransition.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.opensymphony.workflow.InvalidInputException 4 | 5 | if (!transientVars.comment) throw new InvalidInputException ("Комментарий обязателен!") -------------------------------------------------------------------------------- /src/main/jira/validators/GroupChecker.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | /* 5 | issue type creation depending on group membership 6 | */ 7 | def groupManager = ComponentAccessor.groupManager 8 | def issueType = issue.issueType.name 9 | 10 | switch (issueType) { 11 | case "Service Request": 12 | groupManager.isUserInGroup(currentUser, "Xtremax") || groupManager.isUserInGroup(currentUser, "GVT") || 13 | groupManager.isUserInGroup(currentUser, "AA") || groupManager.isUserInGroup(currentUser, "CA") 14 | break 15 | case "Incident": 16 | groupManager.isUserInGroup(currentUser, "Xtremax") || groupManager.isUserInGroup(currentUser, "GVT") || 17 | groupManager.isUserInGroup(currentUser, "AM") || groupManager.isUserInGroup(currentUser, "AA") || 18 | groupManager.isUserInGroup(currentUser, "CA") || groupManager.isUserInGroup(currentUser, "Finance") || 19 | groupManager.isUserInGroup(currentUser, "SIRO") 20 | break 21 | case "Problem": 22 | case "Change": 23 | groupManager.isUserInGroup(currentUser, "Xtremax") || groupManager.isUserInGroup(currentUser, "GVT") 24 | break 25 | } -------------------------------------------------------------------------------- /src/main/jira/validators/LinkedIssueFromCertainProjectInClosedStatus.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | 5 | //On the project HEPROD - allow HEC Request to progress 'To Approval' Only if it has a linked HEC Request. 6 | //Link type should be 'VAL HECReq reference'. The behavior should be so that issues linked in this way are 'Closed'. 7 | 8 | if (issue.key.contains("HEPROD-")) { 9 | def VALHECReqReference = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id).findAll { 10 | it.linkTypeId == 10400 && it.destinationObject.key.contains("HEVAL-") && 11 | it.destinationObject.issueType.name == "HEC Request" 12 | } 13 | if (VALHECReqReference) VALHECReqReference.every {it.destinationObject.status.name == "Closed"} 14 | else false 15 | } else true -------------------------------------------------------------------------------- /src/main/jira/validators/SlAndTextareaValuesMulitiValidation.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.fields.CustomField 5 | 6 | //cfs instruction 1-20 of select list type 7 | def slIds = [12341L, 12349L, 12351L, 12352L, 12353L, 12354L, 12355L, 12356L, 12357L, 12358L, 12359L, 12342L, 12360L, 8 | 12343L, 12344L, 12345L, 12346L, 12348L, 12350L, 12347L] 9 | def slCfs = [] 10 | slIds.each { id -> 11 | slCfs.add(ComponentAccessor.getCustomFieldManager().getCustomFieldObject(id)) 12 | } 13 | def selectListValidation = !slCfs.any { cf -> ((String)issue.getCustomFieldValue((CustomField) cf)) in ["Open", "Block delivery"]} 14 | 15 | //cfs instruction 1-20 of textarea type 16 | def textIds = [12300L, 12309L, 12310L, 12311L, 12312L, 12340, 12314L, 12315L, 12316L, 12317L, 12318L, 12301L, 12319L, 17 | 12302L, 12303L, 12304L, 12305L, 12306L, 12307L, 12308L] 18 | def textCfs = [] 19 | textIds.each { id -> 20 | textCfs.add(ComponentAccessor.getCustomFieldManager().getCustomFieldObject(id)) 21 | } 22 | def textValidation = !textCfs.any{cf -> ((String)issue.getCustomFieldValue((CustomField) cf)) == null} 23 | 24 | return (textValidation && selectListValidation) -------------------------------------------------------------------------------- /src/main/jira/validators/TableGridFieldRequired.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.fields.CustomField 5 | import com.opensymphony.workflow.InvalidInputException 6 | /** 7 | * docs: https://docs.idalko.com/tgng/pages/viewpage.action?pageId=26183994 8 | */ 9 | def tgeCustomField = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 10 | it.name == "Immediate actions (corrections)" 11 | } as CustomField 12 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser.directoryUser 13 | Class dataManagerClass = ComponentAccessor.pluginAccessor.classLoader 14 | .findClass("com.idalko.jira.plugins.igrid.api.data.TGEGridTableDataManager") 15 | def tgeGridDataManager = ComponentAccessor.getOSGiComponentInstanceOfType(dataManagerClass) 16 | List> gridDataList = new ArrayList>() 17 | def result = new StringBuilder() 18 | try { 19 | def gridData = tgeGridDataManager.readGridDataInEditMode(issue, tgeCustomField, null, null, 0, 10, user) 20 | gridDataList = gridData.values 21 | result.append("Grid ID=" + tgeCustomField.id + " data in edit mode: " + gridDataList) 22 | } catch (Exception e) { 23 | result.append("Grid ID=" + tgeCustomField.id + " data in edit mode cannot be retrieved: " + e.message + "\n") 24 | } 25 | if (gridDataList.empty) 26 | throw new InvalidInputException(tgeCustomField.id, "Add at least one record to 'Immediate actions (corrections)' to proceed") -------------------------------------------------------------------------------- /src/main/jira/validators/TableGridFieldRequiredTransition.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.fields.CustomField 5 | import com.opensymphony.workflow.InvalidInputException 6 | import org.apache.log4j.Level 7 | import org.apache.log4j.Logger 8 | import webwork.action.ActionContext 9 | 10 | def log = Logger.getLogger("check-me") 11 | log.setLevel(Level.DEBUG) 12 | def fieldName = "Investigation Details Table" 13 | def tgeCustomField = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find { 14 | it.name == fieldName 15 | } as CustomField 16 | log.debug("issue: " + issue.key) 17 | log.debug("tgeCustomField:" + tgeCustomField.id) 18 | def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser.directoryUser 19 | Class dataManagerClass = ComponentAccessor.pluginAccessor.getClassLoader() 20 | .findClass("com.idalko.jira.plugins.igrid.api.data.TGEGridTableDataManager") 21 | def tgeGridDataManager = ComponentAccessor.getOSGiComponentInstanceOfType(dataManagerClass) 22 | List> gridDataList = new ArrayList>() 23 | def result = new StringBuilder() 24 | try { 25 | def gridData = tgeGridDataManager.readGridDataInEditMode(issue, tgeCustomField, null, null, 0, 10, user) 26 | gridDataList = gridData.values 27 | result.append("Grid ID=" + tgeCustomField.id + " data in edit mode: " + gridDataList) 28 | log.debug(result) 29 | } catch (Exception e) { 30 | result.append("Grid ID=" + tgeCustomField.id + " data in edit mode cannot be retrieved: " + e.getMessage() + "\n") 31 | log.debug(result) 32 | } 33 | 34 | def params = ActionContext.request.parameterMap 35 | def tgeValueFromScreen = params.get(tgeCustomField.id) as String 36 | log.debug(fieldName + " (grid values from screen): " + tgeValueFromScreen) 37 | log.debug(tgeValueFromScreen) 38 | log.debug("gridDataList " + gridDataList.size()) 39 | if (gridDataList.empty) { // always true, except creation screen - seems bug (Jira v8.3.4; iDalko Table Grid plugin Version:1.29.11) 40 | def tgeValueBeforeTransition = tgeGridDataManager.readGridData(issue.id, tgeCustomField.idAsLong, null, null, 0, 10, user) 41 | log.debug(tgeValueBeforeTransition) 42 | if (!tgeValueFromScreen.contains("add")) { 43 | throw new InvalidInputException(tgeCustomField.id, "Add at least one record to" + fieldName + " to proceed") 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/main/jira/validators/transition_screens/AssigneeInCertainGroupRelatedToGroupPickerCF.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators.transition_screens 2 | 3 | import com.opensymphony.workflow.InvalidInputException 4 | import webwork.action.ActionContext 5 | 6 | def request = ActionContext.request 7 | if (request) { 8 | def parameterMap = request.parameterMap 9 | log.warn "parameterMap " + parameterMap.toString() 10 | def groupPickerVal = parameterMap.get("customfield_10413").toString() 11 | log.warn "groupPickerVal " + groupPickerVal 12 | def assignee = parameterMap.get("assignee").toString() 13 | log.warn assignee 14 | // for null value 15 | if (groupPickerVal == "[]") { 16 | throw new InvalidInputException ('Пожалуйста, укажите значение в поле "Рабочая группа".') 17 | } 18 | else if (groupPickerVal == "[Service Desk]") { 19 | throw new InvalidInputException ('Рабочая группа не должна быть Service Desk.') 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/jira/validators/transition_screens/ValidateAnyCustomFieldOnTheScreen.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators.transition_screens 2 | 3 | import webwork.action.ActionContext 4 | import com.opensymphony.workflow.InvalidInputException 5 | 6 | def request = ActionContext.request 7 | if (request) { 8 | def cfValue = request.parameterMap.get("customfield_10007").toString() 9 | // [-1] is an expected null value. 10 | if (cfValue == "[-1]") throw new InvalidInputException ("Please specify Extension") 11 | } -------------------------------------------------------------------------------- /src/main/jira/validators/transition_screens/fixVersionsValidation.groovy: -------------------------------------------------------------------------------- 1 | package jira.validators.transition_screens 2 | 3 | import com.atlassian.jira.component.ComponentAccessor 4 | import com.atlassian.jira.issue.Issue 5 | import com.atlassian.jira.issue.customfields.option.LazyLoadedOption 6 | import com.opensymphony.workflow.InvalidInputException 7 | import webwork.action.ActionContext 8 | 9 | def request = ActionContext.request 10 | if (!request) return 11 | 12 | def parameterMap = request.parameterMap 13 | switch (issue.issueType.name) { 14 | case "Bug": 15 | def fixVersion = parameterMap.get("fixVersions") 16 | if (!fixVersion) 17 | throw new InvalidInputException("fixVersions", "Fix Version/s cannot be empty!") 18 | break 19 | case "Support Ticket": 20 | def supportTicketClassificationVal = getCustomFieldValue("Support Ticket Classification", issue) as LazyLoadedOption 21 | def fixVersionVal = parameterMap.get("fixVersions") 22 | def resolutionVal = parameterMap.get("resolution") as List 23 | def resolutionDoneId = ComponentAccessor.constantsManager.resolutions.find { it.name == "Done"}?.id 24 | if (!fixVersionVal && resolutionVal.first() == resolutionDoneId && supportTicketClassificationVal?.value in ["Bug", "FN", "FP"]) 25 | throw new InvalidInputException("fixVersions", "Fix Version/s cannot be empty!") 26 | break 27 | } 28 | 29 | static Object getCustomFieldValue(String customFieldName, Issue issue) { 30 | ComponentAccessor.customFieldManager.getCustomFieldObjects(issue) 31 | .find { it.name == customFieldName }?.getValue(issue) 32 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/CheckDueDateAndLeaveComment.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners 2 | 3 | import kong.unirest.Unirest 4 | 5 | logger.info("Working with ${issue.key}") 6 | assert issue.fields.issuetype.name.toString() in ["Action", "Effectiveness check"] 7 | 8 | def dueDateValue = issue.fields.duedate as String 9 | assert dueDateValue != null 10 | def parentDueDateValue = Unirest.get("/rest/api/2/issue/${issue.fields.parent.key}").asObject(Map).body.fields.duedate as String 11 | assert parentDueDateValue != null 12 | 13 | def dateFormat = "yyyy-MM-dd" 14 | def childDueDate = new Date().parse(dateFormat, dueDateValue) 15 | def parentDueDate = new Date().parse(dateFormat, parentDueDateValue) 16 | 17 | if (childDueDate.after(parentDueDate)) { 18 | setDueDate(issue, parentDueDateValue) 19 | def commentBody = "Due Date was updated automatically because the due date of the sub-task cannot be later then it's parent duedate" 20 | addComment(issue, commentBody) 21 | } 22 | 23 | static addComment(issue, commentBody) { 24 | Unirest.post("/rest/api/2/issue/${issue.key}/comment") 25 | .header('Content-Type', 'application/json') 26 | .body([body:commentBody]).asObject(Map) 27 | } 28 | 29 | static setDueDate(issue, String date) { 30 | //yyyy-MM-dd 31 | Unirest.put("/rest/api/2/issue/${issue.key}") 32 | .header('Content-Type', 'application/json') 33 | .queryString("notifyUsers", Boolean.FALSE) 34 | .body([fields:[duedate:date]]).asString() 35 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/SumStoryPointsOfSubTasks.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners 2 | 3 | if (issue.fields.issuetype.name.equals("Sub-task")){ 4 | def issueParent = get('/rest/api/2/issue/' + issue.fields.parent.key).asObject(Map) 5 | sumStoryPoints(issueParent.body) 6 | } 7 | else{ 8 | if (issue.fields.issuetype.name.equals("Story")) 9 | if (issue.fields.subtasks.size() > 0) 10 | sumStoryPoints(issue) 11 | } 12 | 13 | void sumStoryPoints(Map issueStory) { 14 | 15 | def subtasks = issueStory.fields.subtasks 16 | Number sum = 0 17 | 18 | subtasks.each{ 19 | def subtaskIssue = get('/rest/api/2/issue/' + it.key).asObject(Map) 20 | if (subtaskIssue.body.fields.customfield_10027 != null) 21 | sum = sum + subtaskIssue.body.fields.customfield_10027 22 | } 23 | 24 | def result = put('/rest/api/2/issue/' + issueStory.key) 25 | .header('Content-Type', 'application/json') 26 | .body([ 27 | fields:[ 28 | customfield_10027: sum 29 | ] 30 | ]) 31 | .asString() 32 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/set_field_value_based_on/AssigneeGroups.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners.set_field_value_based_on 2 | 3 | logger.info("Working with ${issue.key}") 4 | 5 | // find field cf "Team" id 6 | def customFields = get("/rest/api/2/field") 7 | .asObject(List) 8 | .body 9 | .findAll { (it as Map).custom } as List 10 | def teamCFId = customFields.find { it.name == "Team" }?.id 11 | logger.info("Team id: ${teamCFId}") 12 | 13 | // check field current value 14 | def teamValue = issue.fields["teamCfId"] as String 15 | logger.info("Issue: ${issue.key}") 16 | logger.info("Team value: ${teamValue}") 17 | 18 | // get assignee's groups 19 | def assigneeSelfLink = issue.fields.assignee.self 20 | logger.info("Assignee Self Link: ${assigneeSelfLink}") 21 | def groups = get(assigneeSelfLink + "&expand=groups").asObject(Map).body.groups?.items?.name as List 22 | logger.info("assignee's groups: ${groups}") 23 | 24 | // calculate new field value 25 | def newValue = null 26 | if (groups?.contains("Escalations")) newValue = "Escalations" 27 | else if (groups?.contains("Core")) newValue = "Moneytime" 28 | else if (groups?.contains("Experiences")) newValue = "Carma" 29 | else if (groups?.contains("Partners")) newValue = "Prez" 30 | else if (groups?.contains("Onboarding")) newValue = "Onboarding" 31 | else if (groups?.contains("Web")) newValue = "Web" 32 | else if (groups?.contains("Product")) newValue = "Product" 33 | else if (groups?.contains("support")) newValue = "Support" 34 | else if (groups?.contains("QA")) newValue = "QA" 35 | else if (groups?.contains("Infra")) newValue = "Infra" 36 | else if (groups?.contains("BD")) newValue = "BD" 37 | else if (groups?.contains("R&D")) newValue = "R&D" 38 | else newValue = "No data regarding assignee's groups" 39 | 40 | // update issue 41 | if (newValue && teamCFId && teamValue == null) { 42 | put("/rest/api/2/issue/${issue.key}") 43 | .queryString("overrideScreenSecurity", Boolean.TRUE) 44 | .header("Content-Type", "application/json") 45 | .body([ 46 | fields: [(teamCFId): newValue] 47 | ]).asString() 48 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/set_field_value_based_on/IssueLinkAndSubTaskDueDate.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners.set_field_value_based_on 2 | 3 | import kong.unirest.Unirest 4 | 5 | def sourceIssueResponse = Unirest.get("/rest/api/2/issue/${issueLink.sourceIssueId}").asObject(Map) 6 | assert sourceIssueResponse.status == 200 7 | def issue = sourceIssueResponse.body 8 | 9 | if (issueLink.issueLinkType.name.toString() == "jira_subtask_link" && issue.fields.issuetype.subtask.toString() == "false") { 10 | logger.info("Working with ${issue.key}") 11 | def subtasks = issue.fields.subtasks.key as List 12 | if (!subtasks.isEmpty()) { 13 | def value = new StringBuilder() 14 | value.append("${issue.key} ${-> issue.fields.issuetype.name} ${-> issue.fields.duedate}\n") 15 | subtasks.each { 16 | def subtask = getIssue(it) 17 | value.append("${subtask.key} ${-> subtask.fields.issuetype.name} ${-> subtask.fields.duedate}\n") 18 | } 19 | def customFields = Unirest.get("/rest/api/2/field").asObject(List).body.findAll { (it as Map).custom } as List 20 | def customFieldId = customFields.find { it.name == "Sub Tasks Due Dates" }?.id 21 | assert customFieldId != null 22 | updateTextField(issue, customFieldId, value) 23 | } 24 | } 25 | 26 | static Map getIssue(issueKey) { 27 | Unirest.get("/rest/api/2/issue/${issueKey}").asObject(Map).body 28 | } 29 | 30 | static updateTextField(issue, customfield_id, value) { 31 | Unirest.put("/rest/api/2/issue/${issue.key}") 32 | .queryString("overrideScreenSecurity", Boolean.TRUE) 33 | .queryString("notifyUsers", Boolean.TRUE) 34 | .header("Content-Type", "application/json") 35 | .body([fields:[(customfield_id):value]]).asString() 36 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/set_field_value_based_on/LabelsReporterGroups.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners.set_field_value_based_on 2 | 3 | logger.info("Working with ${issue.key}") 4 | 5 | // find field id 6 | def customFields = get("/rest/api/2/field") 7 | .asObject(List) 8 | .body 9 | .findAll { (it as Map).custom } as List 10 | 11 | def detectedByCFId = customFields.find { it.name == "Detected By" }?.id 12 | logger.info("Detected By id: ${detectedByCFId}") 13 | 14 | // check field current value 15 | def detectedByValue = issue.fields["detectedByCFId"] as String 16 | logger.info("Detected By value: ${detectedByValue}") 17 | 18 | // get reporter's groups 19 | def reporterSelfLink = issue.fields.reporter.self 20 | logger.info("Assignee Self Link: ${reporterSelfLink}") 21 | def groups = get("${reporterSelfLink}&expand=groups").asObject(Map).body.groups?.items?.name as List 22 | logger.info("reporter's groups: ${groups}") 23 | 24 | // get labels 25 | def labels = issue.fields.labels as List 26 | logger.info("Labels: ${labels}") 27 | 28 | // calculate new field value 29 | def newValue = null 30 | if (labels?.contains("jira_escalated") || groups?.contains("support")) newValue = "Support" 31 | else if (groups?.contains("QA")) newValue = "QA" 32 | else if (groups?.contains("Product")) newValue = "Product" 33 | else if (groups?.contains("R&D")) newValue = "R&D" 34 | else if (groups?.contains("BD")) newValue = "Partners" 35 | else if (groups?.contains("Marketing")) newValue = "Marketing" 36 | else newValue = "Other" 37 | 38 | //update issue 39 | if (newValue && detectedByCFId && detectedByValue == null) { 40 | put("/rest/api/2/issue/${issue.key}") 41 | .queryString("overrideScreenSecurity", Boolean.TRUE) 42 | .header("Content-Type", "application/json") 43 | .body([ 44 | fields: [(detectedByCFId): newValue] 45 | ]).asString() 46 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/set_field_value_based_on/LabelsReporterGroupsFieldValue.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners.set_field_value_based_on 2 | 3 | logger.info("Working with ${issue.key}") 4 | 5 | //get fields 6 | def customFields = get("/rest/api/2/field") 7 | .asObject(List) 8 | .body 9 | .findAll { (it as Map).custom } as List 10 | 11 | // get labels 12 | def labels = issue.fields.labels as List 13 | logger.info("Labels: ${labels}") 14 | 15 | // find value of "Requested by" field (label type) 16 | def requestedByCFId = customFields.find { it.name == "Requested by" }?.id 17 | logger.info("Requested by id: ${requestedByCFId}") 18 | def requestedByValue = issue.fields[requestedByCFId]?.value 19 | logger.info("Requested By value: ${requestedByValue}") 20 | 21 | // get reporter's groups 22 | def reporterSelfLink = issue.fields.reporter.self 23 | logger.info("Reporter Self Link: ${reporterSelfLink}") 24 | def groups = get("${reporterSelfLink}&expand=groups").asObject(Map).body.groups?.items?.name as List 25 | logger.info("reporter's groups: ${groups}") 26 | 27 | // update field "By Customer" 28 | if (requestedByValue != null || labels.contains("jira_escalated") || groups?.contains("support")) { 29 | def byCustomerCfId = customFields.find { it.name == "By Customer" }?.id 30 | put("/rest/api/2/issue/${issue.key}") 31 | .queryString("overrideScreenSecurity", Boolean.TRUE) 32 | .header("Content-Type", "application/json") 33 | .body([ 34 | fields: [(byCustomerCfId): "True"] 35 | ]).asString() 36 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/set_field_value_based_on/LastComment.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners.set_field_value_based_on 2 | 3 | import kong.unirest.Unirest 4 | import java.text.SimpleDateFormat 5 | 6 | def issue = getIssue("QMSNC-1") // for testing in console only 7 | 8 | logger.info("Working with ${issue.key}") 9 | def customFields = Unirest.get("/rest/api/2/field").asObject(List).body.findAll { (it as Map).custom } as List 10 | def customFieldId = customFields.find { it.name == "Latest Comment" }?.id 11 | def comments = getComments(issue) 12 | 13 | if (!comments.isEmpty()) { 14 | def lastComment = comments.last() 15 | // formatting 16 | def formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX") 17 | def created = formatter.parse(lastComment.created) 18 | formatter = new SimpleDateFormat("dd/MM/yyyy") 19 | created = formatter.format(created) 20 | def lastCommentFormatted = "By ${lastComment.author.displayName}, ${created}:\n${lastComment.body}" 21 | 22 | updateTextField(issue, customFieldId, lastCommentFormatted) 23 | } 24 | 25 | static def getIssue(issueKey) { 26 | Unirest.get("/rest/api/2/issue/${issueKey}").asObject(Map).body 27 | } 28 | 29 | static List getComments(issue) { 30 | Unirest.get("/rest/api/2/issue/${issue.key}/comment").asObject(Map).body.comments as List 31 | } 32 | 33 | static updateTextField(issue, customfield_id, value) { 34 | Unirest.put("/rest/api/2/issue/${issue.key}") 35 | .queryString("overrideScreenSecurity", Boolean.TRUE) 36 | .queryString("notifyUsers", Boolean.TRUE) 37 | .header("Content-Type", "application/json") 38 | .body([ 39 | fields:[ 40 | (customfield_id):value 41 | ] 42 | ]).asString() 43 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/listeners/set_field_value_based_on/Votes.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.listeners.set_field_value_based_on 2 | 3 | import kong.unirest.Unirest 4 | 5 | if (!changelog.toString().contains("Requests Count")) return 6 | 7 | def requestVotes = Unirest.get("/rest/api/2/issue/${issue.key}/votes").asObject(Map) 8 | assert requestVotes.status == 200 9 | def votes = requestVotes.body.votes as Integer 10 | 11 | def requestCF = Unirest.get("/rest/api/2/field").asObject(List) 12 | assert requestCF.status == 200 13 | def cfs = requestCF.body.findAll { (it as Map).custom } as List 14 | 15 | def calcRankId = cfs.find { it.name == "Calculated Rank" }?.id 16 | assert calcRankId != null 17 | 18 | def requestCountId = cfs.find { it.name == "Requests Count" }?.id 19 | assert requestCountId != null 20 | 21 | def requestCountVal = issue.fields["${requestCountId}"] as Integer 22 | assert requestCountVal != null 23 | 24 | def calcRankVal = requestCountVal * 0.4 + votes * 0.6 25 | 26 | def result = Unirest.put("/rest/api/2/issue/${issue.key}") 27 | .queryString("overrideScreenSecurity", Boolean.TRUE) 28 | .queryString("notifyUsers", Boolean.FALSE) 29 | .header("Content-Type", "application/json") 30 | .body([ 31 | fields: [ 32 | (calcRankId): calcRankVal 33 | ] 34 | ]).asString() 35 | assert result.status == 204 -------------------------------------------------------------------------------- /src/main/jira_cloud/post_functions/SetFieldsValues.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.post_functions 2 | 3 | def customFields = get("/rest/api/2/field") 4 | .asObject(List) 5 | .body 6 | .findAll { (it as Map).custom } as List 7 | 8 | def toUpdate1CfId = customFields.find { it.name == 'Custom Field 1' }?.id 9 | def toUpdate2CfId = customFields.find { it.name == 'Custom Field 2' }?.id 10 | def toUpdate3CfId = customFields.find { it.name == 'Custom Field 3' }?.id 11 | 12 | def tomorrowStr = (new Date() + 1).format("yyyy-MM-dd'T'HH:mm:ssZ", TimeZone.getTimeZone("UTC")) // date format in iso8601 13 | def resp = put("/rest/api/2/issue/\${issue.key}") 14 | .header('Content-Type', 'application/json') 15 | .body([ 16 | fields: [ 17 | fixVersions : ['1.1'], 18 | component : ['MyComponent'], 19 | description : 'A generated description', 20 | (toUpdate1CfId): 'Some text value', 21 | (toUpdate2CfId): tomorrowStr, 22 | (toUpdate3CfId): 'admin' 23 | ] 24 | ]) 25 | .asString() 26 | assert resp.status == 204 27 | 28 | /* 29 | curl --user email@example.com: \ 30 | --header 'Accept: application/json' \ 31 | --url 'https://your-domain.atlassian.net/rest/api/2/user/groups' 32 | { 33 | "name": "jira-administrators", 34 | "self": "http://www.example.com/jira/rest/api/2/group?groupname=jira-administrators" 35 | } 36 | */ 37 | 38 | -------------------------------------------------------------------------------- /src/main/jira_cloud/post_functions/SetSprint.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.post_functions 2 | 3 | logger.info("Working with ${issue.key}") 4 | 5 | // get fields and find id 6 | def customFields = get("/rest/api/2/field") 7 | .asObject(List) 8 | .body 9 | .findAll { (it as Map).custom } as List 10 | 11 | def sprintId = customFields.find { it.name == "Sprint" }?.id 12 | logger.info("Sprint id: ${sprintId}") 13 | 14 | // get current sprint 15 | def sprintValue = issue.fields[sprintId] as String 16 | logger.info("Sprint value: ${sprintValue}") 17 | 18 | if (!sprintValue || (sprintValue && !sprintValue.contains("Urgent Todo"))) { 19 | 20 | // set sprint with id=20 ("This week" sprint) 21 | put("/rest/api/2/issue/${issue.key}") 22 | .queryString("overrideScreenSecurity", Boolean.TRUE) 23 | .header("Content-Type", "application/json") 24 | .body([ 25 | fields: [(sprintId): 20] 26 | ]).asString() 27 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/post_functions/set_field_value_based_on/MultipleValuesFromOtherFields.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.post_functions.set_field_value_based_on 2 | // get list of fields and find required values 3 | def customFields = get("/rest/api/2/field").asObject(List).body.findAll { (it as Map).custom } as List 4 | 5 | // get field id and value for confition 6 | def classificationId = customFields.find { it.name == "Classification" }?.id 7 | def classificationValue = getCustomFiledValue(issue, customFields.find { it.name == "Classification" }?.id) 8 | 9 | //logic 10 | if (!classificationValue) { 11 | def complexityValue = getCustomFiledValue(issue, customFields.find { it.name == "Complexity" }?.id) 12 | def scopeValue = getCustomFiledValue(issue, customFields.find { it.name == "Scope" }?.id) 13 | def rrValue = getCustomFiledValue(issue, customFields.find { it.name == "Reporting or recall" }?.id) 14 | if (complexityValue == "Multiple components out of control" || 15 | scopeValue.any{ it in ["Multiple product, process or document","Suspended release","Multiple sites"]} || 16 | rrValue == "Required") updateSelectList(issue, classificationId, "SNC") 17 | } 18 | 19 | // functions 20 | def getCustomFiledValue(issue, customfield_id) { 21 | def result = get("/rest/api/2/issue/${issue.key}?fields=${customfield_id}") 22 | .header('Content-Type', 'application/json') 23 | .asObject(Map) 24 | result.status == 200 ? result.body.fields[customfield_id]?.value : null 25 | } 26 | 27 | def updateSelectList(issue, customfield_id, value) { 28 | def optionId = get("/rest/api/2/issue/${issue.key}/editmeta") 29 | .header('Content-Type', 'application/json').asObject(Map).body.fields[customfield_id]?.allowedValues?.find { it.value == value}?.id 30 | if (optionId) { 31 | put("/rest/api/2/issue/${issue.key}") 32 | .queryString("overrideScreenSecurity", Boolean.TRUE) 33 | .header("Content-Type", "application/json") 34 | .body([ 35 | fields: [ 36 | (customfield_id):[value:"${value}"] 37 | ] 38 | ]).asString() 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/post_functions/set_field_value_based_on/ReporterGroups.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.post_functions.set_field_value_based_on 2 | // condition that starts script if the field is empty 3 | def value = issue.fields["customfield_10036"] as String 4 | return value == null 5 | 6 | // script 7 | def issueEditMeta = get("/rest/api/2/issue/" + issue.key + "/editmeta").asObject(Map) 8 | def options = issueEditMeta.body.fields.customfield_10036.allowedValues.value 9 | def userGroups = get("/rest/api/2/user/groups?key=" + issue.fields.reporter.key).asObject(List).body.name 10 | def commons = userGroups.intersect(options) 11 | put("/rest/api/2/issue/" + issue.key) 12 | .queryString("overrideScreenSecurity", Boolean.TRUE) 13 | .header('Content-Type', 'application/json') 14 | .body([ 15 | fields: [ 16 | customfield_10036: [value: commons[0]] 17 | ] 18 | ]).asString() -------------------------------------------------------------------------------- /src/main/jira_cloud/script_console/UpdateCFSelectListBasedOnReportersGroup.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.script_console 2 | 3 | def issueKey = "JPFCC-1" 4 | def issue = get('/rest/api/2/issue/' + issueKey).asObject(Map).body 5 | 6 | if (getCustomFiledValue(issueKey, "customfield_10036") == null) 7 | { 8 | def issueEditMeta = get("/rest/api/2/issue/" + issueKey + "/editmeta").asObject(Map) 9 | def options = issueEditMeta.body.fields.customfield_10036.allowedValues.value 10 | def reporter = issue.fields.reporter.key 11 | def userGroups = get('/rest/api/2/user/groups?key=' + reporter).asObject(List).body.name 12 | def commons = userGroups.intersect(options) 13 | def result = put("/rest/api/2/issue/" + issueKey) 14 | .queryString("overrideScreenSecurity", Boolean.TRUE) 15 | .header('Content-Type', 'application/json') 16 | .body([ 17 | fields: [ 18 | customfield_10036: [value: commons[0]] 19 | ] 20 | ]).asString() 21 | 22 | if (result.status == 204) { 23 | return 'Success' 24 | } else { 25 | return "${result.status}: ${result.body}" 26 | } 27 | } 28 | 29 | String getCustomFiledValue(String issueKey, String customFieldName) { 30 | def result = get("/rest/api/2/issue/" + issueKey + "?fields=${customFieldName}") 31 | .header('Content-Type', 'application/json') 32 | .asObject(Map) 33 | if (result.status == 200) { 34 | try { 35 | return result.body.fields[customFieldName].value 36 | } catch (NullPointerException e) { 37 | return null 38 | } 39 | } else { 40 | return null 41 | } 42 | } 43 | //retrieve the custom field ID for the 'Scrum Team' custom field 44 | //def fields = get('/rest/api/2/field').asObject(List).body as List 45 | //def customFieldId = fields.find { it.name == 'Scrum Team'}.id as String //output customfield_10036 46 | //get all fields 47 | //def fields = get('/rest/api/2/field').asObject(List).body as List 48 | //def customFieldValue = (issue.fields[customFieldId] as Map)?.value -------------------------------------------------------------------------------- /src/main/jira_cloud/script_console/bulk_issue_creation/epicsWithoutIssues.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.script_console.bulk_issue_creation 2 | 3 | import kong.unirest.Unirest 4 | 5 | int amountOfIssues = 8 6 | def projectKey = "TA2" 7 | def epicSummary = "Test Summary" 8 | def epicDescription = "Test Description" 9 | def epicName = "Test Epic" 10 | def epicNameField = "Epic Name" 11 | def customFields = customFields 12 | def epicNameFieldId = customFields.find { it.name == epicNameField }?.id 13 | def epicType = Unirest.get("/rest/api/2/issuetype").asObject(List).body.find { it["name"] == "Epic" }["id"] 14 | 15 | amountOfIssues.times { 16 | Unirest.post('/rest/api/2/issue') 17 | .header('Content-Type', 'application/json') 18 | .body( 19 | [ 20 | fields: [ 21 | summary : epicSummary, 22 | description : epicDescription, 23 | project : [key: projectKey], 24 | issuetype : [id: epicType], 25 | (epicNameFieldId): epicName 26 | ] 27 | ]).asString().body 28 | } 29 | 30 | static List getCustomFields() { 31 | Unirest.get("/rest/api/2/field") 32 | .header('Content-Type', 'application/json') 33 | .asObject(List) 34 | .body 35 | .findAll { (it as Map).custom } as List 36 | } -------------------------------------------------------------------------------- /src/main/jira_cloud/templates/GitLab.groovy: -------------------------------------------------------------------------------- 1 | package jira_cloud.templates 2 | 3 | import kong.unirest.Unirest 4 | 5 | static def getAllUsers(String gitLabApiUrl, String gitLabAdminToken) { 6 | Unirest.get("${gitLabApiUrl}/users") 7 | .header("PRIVATE-TOKEN", gitLabAdminToken) 8 | .asObject(List) 9 | } 10 | 11 | static List getUserByEmail(String gitLabApiUrl, String gitLabAdminToken, String email) { 12 | def result = Unirest.get("${gitLabApiUrl}/users") 13 | .header("PRIVATE-TOKEN", gitLabAdminToken) 14 | .queryString("search", email) 15 | .asObject(List) 16 | assert result.status == 200 17 | return result.body 18 | } 19 | 20 | static Map createImpersonationToken(String gitLabApiUrl, String gitLabAdminToken, int userId, String tokenName) { 21 | def result = Unirest.post("${gitLabApiUrl}/users/${userId}/impersonation_tokens") 22 | .header("PRIVATE-TOKEN", gitLabAdminToken) 23 | .header("Content-Type", "application/json") 24 | .body([ 25 | name : tokenName, 26 | scopes: [ 27 | "api" 28 | ] 29 | ]).asObject(Map) 30 | assert result.status == 201 31 | return result.body 32 | } 33 | 34 | static Map createBranch(String gitLabApiUrl, String gitLabToken, int gitLabProjectId, String branchName, String createBranchFrom) { 35 | def result = Unirest.post("${gitLabApiUrl}/projects/${gitLabProjectId}/repository/branches") 36 | .header("PRIVATE-TOKEN", gitLabToken) 37 | .header("Content-Type", "application/json") 38 | .body([ 39 | branch: branchName, 40 | ref: createBranchFrom 41 | ]).asObject(Map) 42 | assert result.status == 201 43 | return result.body 44 | } 45 | 46 | static def revokeImpersonationToken(String gitLabApiUrl, String gitLabAdminToken, int userId, int tokenId) { 47 | def result = Unirest.delete("${gitLabApiUrl}/users/${userId}/impersonation_tokens/${tokenId}") 48 | .header("PRIVATE-TOKEN", gitLabAdminToken).asString() 49 | assert result.status == 204 50 | } --------------------------------------------------------------------------------