package JIRA::API::Client::Impl 0.01;
# DO NOT EDIT! This is an autogenerated file.
use 5.020;
use Moo 2;
use experimental 'signatures';
use PerlX::Maybe;
use Carp 'croak';

# These should go into a ::Role
use YAML::PP;
use Mojo::UserAgent;
use Mojo::URL;
use Mojo::JSON 'encode_json', 'decode_json';
use OpenAPI::Modern;

use Future::Mojo;

use JIRA::API::ActorInputBean;
use JIRA::API::ActorsMap;
use JIRA::API::AddFieldBean;
use JIRA::API::AddGroupBean;
use JIRA::API::AddNotificationsDetails;
use JIRA::API::AnnouncementBannerConfiguration;
use JIRA::API::AnnouncementBannerConfigurationUpdate;
use JIRA::API::Application;
use JIRA::API::ApplicationProperty;
use JIRA::API::ApplicationRole;
use JIRA::API::AssociateFieldConfigurationsWithIssueTypesRequest;
use JIRA::API::AssociatedItemBean;
use JIRA::API::Attachment;
use JIRA::API::AttachmentArchive;
use JIRA::API::AttachmentArchiveEntry;
use JIRA::API::AttachmentArchiveImpl;
use JIRA::API::AttachmentArchiveItemReadable;
use JIRA::API::AttachmentArchiveMetadataReadable;
use JIRA::API::AttachmentMetadata;
use JIRA::API::AttachmentSettings;
use JIRA::API::AuditRecordBean;
use JIRA::API::AuditRecords;
use JIRA::API::AutoCompleteSuggestion;
use JIRA::API::AutoCompleteSuggestions;
use JIRA::API::AvailableDashboardGadget;
use JIRA::API::AvailableDashboardGadgetsResponse;
use JIRA::API::Avatar;
use JIRA::API::AvatarUrlsBean;
use JIRA::API::Avatars;
use JIRA::API::BulkCustomFieldOptionCreateRequest;
use JIRA::API::BulkCustomFieldOptionUpdateRequest;
use JIRA::API::BulkIssueIsWatching;
use JIRA::API::BulkIssuePropertyUpdateRequest;
use JIRA::API::BulkOperationErrorResult;
use JIRA::API::BulkPermissionGrants;
use JIRA::API::BulkPermissionsRequestBean;
use JIRA::API::BulkProjectPermissionGrants;
use JIRA::API::BulkProjectPermissions;
use JIRA::API::ChangeDetails;
use JIRA::API::ChangeFilterOwner;
use JIRA::API::ChangedValueBean;
use JIRA::API::ChangedWorklog;
use JIRA::API::ChangedWorklogs;
use JIRA::API::Changelog;
use JIRA::API::ColumnItem;
use JIRA::API::Comment;
use JIRA::API::ComponentIssuesCount;
use JIRA::API::ComponentWithIssueCount;
use JIRA::API::CompoundClause;
use JIRA::API::Configuration;
use JIRA::API::ConnectCustomFieldValue;
use JIRA::API::ConnectCustomFieldValues;
use JIRA::API::ConnectModule;
use JIRA::API::ConnectModules;
use JIRA::API::ConnectWorkflowTransitionRule;
use JIRA::API::ContainerForProjectFeatures;
use JIRA::API::ContainerForRegisteredWebhooks;
use JIRA::API::ContainerForWebhookIDs;
use JIRA::API::ContainerOfWorkflowSchemeAssociations;
use JIRA::API::Context;
use JIRA::API::ContextForProjectAndIssueType;
use JIRA::API::ContextualConfiguration;
use JIRA::API::ConvertedJQLQueries;
use JIRA::API::CreateCustomFieldContext;
use JIRA::API::CreateNotificationSchemeDetails;
use JIRA::API::CreatePriorityDetails;
use JIRA::API::CreateProjectDetails;
use JIRA::API::CreateResolutionDetails;
use JIRA::API::CreateUiModificationDetails;
use JIRA::API::CreateUpdateRoleRequestBean;
use JIRA::API::CreateWorkflowCondition;
use JIRA::API::CreateWorkflowDetails;
use JIRA::API::CreateWorkflowStatusDetails;
use JIRA::API::CreateWorkflowTransitionDetails;
use JIRA::API::CreateWorkflowTransitionRule;
use JIRA::API::CreateWorkflowTransitionRulesDetails;
use JIRA::API::CreateWorkflowTransitionScreenDetails;
use JIRA::API::CreatedIssue;
use JIRA::API::CreatedIssues;
use JIRA::API::CustomContextVariable;
use JIRA::API::CustomFieldConfigurations;
use JIRA::API::CustomFieldContext;
use JIRA::API::CustomFieldContextDefaultValue;
use JIRA::API::CustomFieldContextDefaultValueCascadingOption;
use JIRA::API::CustomFieldContextDefaultValueDate;
use JIRA::API::CustomFieldContextDefaultValueDateTime;
use JIRA::API::CustomFieldContextDefaultValueFloat;
use JIRA::API::CustomFieldContextDefaultValueForgeDateTimeField;
use JIRA::API::CustomFieldContextDefaultValueForgeGroupField;
use JIRA::API::CustomFieldContextDefaultValueForgeMultiGroupField;
use JIRA::API::CustomFieldContextDefaultValueForgeMultiStringField;
use JIRA::API::CustomFieldContextDefaultValueForgeMultiUserField;
use JIRA::API::CustomFieldContextDefaultValueForgeNumberField;
use JIRA::API::CustomFieldContextDefaultValueForgeObjectField;
use JIRA::API::CustomFieldContextDefaultValueForgeStringField;
use JIRA::API::CustomFieldContextDefaultValueForgeUserField;
use JIRA::API::CustomFieldContextDefaultValueLabels;
use JIRA::API::CustomFieldContextDefaultValueMultiUserPicker;
use JIRA::API::CustomFieldContextDefaultValueMultipleGroupPicker;
use JIRA::API::CustomFieldContextDefaultValueMultipleOption;
use JIRA::API::CustomFieldContextDefaultValueMultipleVersionPicker;
use JIRA::API::CustomFieldContextDefaultValueProject;
use JIRA::API::CustomFieldContextDefaultValueReadOnly;
use JIRA::API::CustomFieldContextDefaultValueSingleGroupPicker;
use JIRA::API::CustomFieldContextDefaultValueSingleOption;
use JIRA::API::CustomFieldContextDefaultValueSingleVersionPicker;
use JIRA::API::CustomFieldContextDefaultValueTextArea;
use JIRA::API::CustomFieldContextDefaultValueTextField;
use JIRA::API::CustomFieldContextDefaultValueURL;
use JIRA::API::CustomFieldContextDefaultValueUpdate;
use JIRA::API::CustomFieldContextOption;
use JIRA::API::CustomFieldContextProjectMapping;
use JIRA::API::CustomFieldContextSingleUserPickerDefaults;
use JIRA::API::CustomFieldContextUpdateDetails;
use JIRA::API::CustomFieldCreatedContextOptionsList;
use JIRA::API::CustomFieldDefinitionJsonBean;
use JIRA::API::CustomFieldOption;
use JIRA::API::CustomFieldOptionCreate;
use JIRA::API::CustomFieldOptionUpdate;
use JIRA::API::CustomFieldReplacement;
use JIRA::API::CustomFieldUpdatedContextOptionsList;
use JIRA::API::CustomFieldValueUpdate;
use JIRA::API::CustomFieldValueUpdateDetails;
use JIRA::API::Dashboard;
use JIRA::API::DashboardDetails;
use JIRA::API::DashboardGadget;
use JIRA::API::DashboardGadgetPosition;
use JIRA::API::DashboardGadgetResponse;
use JIRA::API::DashboardGadgetSettings;
use JIRA::API::DashboardGadgetUpdateRequest;
use JIRA::API::DefaultShareScope;
use JIRA::API::DefaultWorkflow;
use JIRA::API::DeleteAndReplaceVersionBean;
use JIRA::API::DeprecatedWorkflow;
use JIRA::API::EntityProperty;
use JIRA::API::EntityPropertyDetails;
use JIRA::API::ErrorCollection;
use JIRA::API::ErrorMessage;
use JIRA::API::EventNotification;
use JIRA::API::FailedWebhook;
use JIRA::API::FailedWebhooks;
use JIRA::API::Field;
use JIRA::API::FieldChangedClause;
use JIRA::API::FieldConfiguration;
use JIRA::API::FieldConfigurationDetails;
use JIRA::API::FieldConfigurationIssueTypeItem;
use JIRA::API::FieldConfigurationItem;
use JIRA::API::FieldConfigurationItemsDetails;
use JIRA::API::FieldConfigurationScheme;
use JIRA::API::FieldConfigurationSchemeProjectAssociation;
use JIRA::API::FieldConfigurationSchemeProjects;
use JIRA::API::FieldConfigurationToIssueTypeMapping;
use JIRA::API::FieldDetails;
use JIRA::API::FieldLastUsed;
use JIRA::API::FieldMetadata;
use JIRA::API::FieldReferenceData;
use JIRA::API::FieldUpdateOperation;
use JIRA::API::FieldValueClause;
use JIRA::API::FieldWasClause;
use JIRA::API::Fields;
use JIRA::API::Filter;
use JIRA::API::FilterDetails;
use JIRA::API::FilterSubscription;
use JIRA::API::FilterSubscriptionsList;
use JIRA::API::FoundGroup;
use JIRA::API::FoundGroups;
use JIRA::API::FoundUsers;
use JIRA::API::FoundUsersAndGroups;
use JIRA::API::FunctionOperand;
use JIRA::API::FunctionReferenceData;
use JIRA::API::GlobalScopeBean;
use JIRA::API::Group;
use JIRA::API::GroupDetails;
use JIRA::API::GroupLabel;
use JIRA::API::GroupName;
use JIRA::API::HealthCheckResult;
use JIRA::API::Hierarchy;
use JIRA::API::HistoryMetadata;
use JIRA::API::HistoryMetadataParticipant;
use JIRA::API::Icon;
use JIRA::API::IconBean;
use JIRA::API::IdBean;
use JIRA::API::IdOrKeyBean;
use JIRA::API::IncludedFields;
use JIRA::API::IssueBean;
use JIRA::API::IssueChangelogIds;
use JIRA::API::IssueCommentListRequestBean;
use JIRA::API::IssueContextVariable;
use JIRA::API::IssueCreateMetadata;
use JIRA::API::IssueEntityProperties;
use JIRA::API::IssueEntityPropertiesForMultiUpdate;
use JIRA::API::IssueEvent;
use JIRA::API::IssueFieldOption;
use JIRA::API::IssueFieldOptionConfiguration;
use JIRA::API::IssueFieldOptionCreateBean;
use JIRA::API::IssueFieldOptionScopeBean;
use JIRA::API::IssueFilterForBulkPropertyDelete;
use JIRA::API::IssueFilterForBulkPropertySet;
use JIRA::API::IssueLink;
use JIRA::API::IssueLinkType;
use JIRA::API::IssueLinkTypes;
use JIRA::API::IssueList;
use JIRA::API::IssueMatches;
use JIRA::API::IssueMatchesForJQL;
use JIRA::API::IssuePickerSuggestions;
use JIRA::API::IssuePickerSuggestionsIssueType;
use JIRA::API::IssueSecurityLevelMember;
use JIRA::API::IssueTransition;
use JIRA::API::IssueTypeCreateBean;
use JIRA::API::IssueTypeDetails;
use JIRA::API::IssueTypeIds;
use JIRA::API::IssueTypeIdsToRemove;
use JIRA::API::IssueTypeInfo;
use JIRA::API::IssueTypeIssueCreateMetadata;
use JIRA::API::IssueTypeScheme;
use JIRA::API::IssueTypeSchemeDetails;
use JIRA::API::IssueTypeSchemeID;
use JIRA::API::IssueTypeSchemeMapping;
use JIRA::API::IssueTypeSchemeProjectAssociation;
use JIRA::API::IssueTypeSchemeProjects;
use JIRA::API::IssueTypeSchemeUpdateDetails;
use JIRA::API::IssueTypeScreenScheme;
use JIRA::API::IssueTypeScreenSchemeDetails;
use JIRA::API::IssueTypeScreenSchemeId;
use JIRA::API::IssueTypeScreenSchemeItem;
use JIRA::API::IssueTypeScreenSchemeMapping;
use JIRA::API::IssueTypeScreenSchemeMappingDetails;
use JIRA::API::IssueTypeScreenSchemeProjectAssociation;
use JIRA::API::IssueTypeScreenSchemeUpdateDetails;
use JIRA::API::IssueTypeScreenSchemesProjects;
use JIRA::API::IssueTypeToContextMapping;
use JIRA::API::IssueTypeUpdateBean;
use JIRA::API::IssueTypeWithStatus;
use JIRA::API::IssueTypeWorkflowMapping;
use JIRA::API::IssueTypesWorkflowMapping;
use JIRA::API::IssueUpdateDetails;
use JIRA::API::IssueUpdateMetadata;
use JIRA::API::IssuesAndJQLQueries;
use JIRA::API::IssuesJqlMetaDataBean;
use JIRA::API::IssuesMetaBean;
use JIRA::API::IssuesUpdateBean;
use JIRA::API::JQLPersonalDataMigrationRequest;
use JIRA::API::JQLQueryWithUnknownUsers;
use JIRA::API::JQLReferenceData;
use JIRA::API::JexpIssues;
use JIRA::API::JexpJqlIssues;
use JIRA::API::JiraExpressionAnalysis;
use JIRA::API::JiraExpressionComplexity;
use JIRA::API::JiraExpressionEvalContextBean;
use JIRA::API::JiraExpressionEvalRequestBean;
use JIRA::API::JiraExpressionEvaluationMetaDataBean;
use JIRA::API::JiraExpressionForAnalysis;
use JIRA::API::JiraExpressionResult;
use JIRA::API::JiraExpressionValidationError;
use JIRA::API::JiraExpressionsAnalysis;
use JIRA::API::JiraExpressionsComplexityBean;
use JIRA::API::JiraExpressionsComplexityValueBean;
use JIRA::API::JiraStatus;
use JIRA::API::JqlFunctionPrecomputationBean;
use JIRA::API::JqlFunctionPrecomputationUpdateBean;
use JIRA::API::JqlFunctionPrecomputationUpdateRequestBean;
use JIRA::API::JqlQueriesToParse;
use JIRA::API::JqlQueriesToSanitize;
use JIRA::API::JqlQuery;
use JIRA::API::JqlQueryClause;
use JIRA::API::JqlQueryClauseOperand;
use JIRA::API::JqlQueryClauseTimePredicate;
use JIRA::API::JqlQueryField;
use JIRA::API::JqlQueryFieldEntityProperty;
use JIRA::API::JqlQueryOrderByClause;
use JIRA::API::JqlQueryOrderByClauseElement;
use JIRA::API::JqlQueryToSanitize;
use JIRA::API::JqlQueryUnitaryOperand;
use JIRA::API::JsonContextVariable;
use JIRA::API::JsonNode;
use JIRA::API::JsonTypeBean;
use JIRA::API::KeywordOperand;
use JIRA::API::License;
use JIRA::API::LicenseMetric;
use JIRA::API::LicensedApplication;
use JIRA::API::LinkGroup;
use JIRA::API::LinkIssueRequestJsonBean;
use JIRA::API::LinkedIssue;
use JIRA::API::ListOperand;
use JIRA::API::ListWrapperCallbackApplicationRole;
use JIRA::API::ListWrapperCallbackGroupName;
use JIRA::API::Locale;
use JIRA::API::MoveFieldBean;
use JIRA::API::MultiIssueEntityProperties;
use JIRA::API::MultipleCustomFieldValuesUpdate;
use JIRA::API::MultipleCustomFieldValuesUpdateDetails;
use JIRA::API::NestedResponse;
use JIRA::API::NewUserDetails;
use JIRA::API::Notification;
use JIRA::API::NotificationEvent;
use JIRA::API::NotificationRecipients;
use JIRA::API::NotificationRecipientsRestrictions;
use JIRA::API::NotificationScheme;
use JIRA::API::NotificationSchemeAndProjectMappingJsonBean;
use JIRA::API::NotificationSchemeEvent;
use JIRA::API::NotificationSchemeEventDetails;
use JIRA::API::NotificationSchemeEventTypeId;
use JIRA::API::NotificationSchemeId;
use JIRA::API::NotificationSchemeNotificationDetails;
use JIRA::API::OperationMessage;
use JIRA::API::Operations;
use JIRA::API::OrderOfCustomFieldOptions;
use JIRA::API::OrderOfIssueTypes;
use JIRA::API::PageBeanChangelog;
use JIRA::API::PageBeanComment;
use JIRA::API::PageBeanComponentWithIssueCount;
use JIRA::API::PageBeanContext;
use JIRA::API::PageBeanContextForProjectAndIssueType;
use JIRA::API::PageBeanContextualConfiguration;
use JIRA::API::PageBeanCustomFieldContext;
use JIRA::API::PageBeanCustomFieldContextDefaultValue;
use JIRA::API::PageBeanCustomFieldContextOption;
use JIRA::API::PageBeanCustomFieldContextProjectMapping;
use JIRA::API::PageBeanDashboard;
use JIRA::API::PageBeanField;
use JIRA::API::PageBeanFieldConfigurationDetails;
use JIRA::API::PageBeanFieldConfigurationIssueTypeItem;
use JIRA::API::PageBeanFieldConfigurationItem;
use JIRA::API::PageBeanFieldConfigurationScheme;
use JIRA::API::PageBeanFieldConfigurationSchemeProjects;
use JIRA::API::PageBeanFilterDetails;
use JIRA::API::PageBeanGroupDetails;
use JIRA::API::PageBeanIssueFieldOption;
use JIRA::API::PageBeanIssueSecurityLevelMember;
use JIRA::API::PageBeanIssueTypeScheme;
use JIRA::API::PageBeanIssueTypeSchemeMapping;
use JIRA::API::PageBeanIssueTypeSchemeProjects;
use JIRA::API::PageBeanIssueTypeScreenScheme;
use JIRA::API::PageBeanIssueTypeScreenSchemeItem;
use JIRA::API::PageBeanIssueTypeScreenSchemesProjects;
use JIRA::API::PageBeanIssueTypeToContextMapping;
use JIRA::API::PageBeanJqlFunctionPrecomputationBean;
use JIRA::API::PageBeanNotificationScheme;
use JIRA::API::PageBeanNotificationSchemeAndProjectMappingJsonBean;
use JIRA::API::PageBeanPriority;
use JIRA::API::PageBeanProject;
use JIRA::API::PageBeanProjectDetails;
use JIRA::API::PageBeanResolutionJsonBean;
use JIRA::API::PageBeanScreen;
use JIRA::API::PageBeanScreenScheme;
use JIRA::API::PageBeanScreenWithTab;
use JIRA::API::PageBeanString;
use JIRA::API::PageBeanUiModificationDetails;
use JIRA::API::PageBeanUser;
use JIRA::API::PageBeanUserDetails;
use JIRA::API::PageBeanUserKey;
use JIRA::API::PageBeanVersion;
use JIRA::API::PageBeanWebhook;
use JIRA::API::PageBeanWorkflow;
use JIRA::API::PageBeanWorkflowScheme;
use JIRA::API::PageBeanWorkflowTransitionRules;
use JIRA::API::PageOfChangelogs;
use JIRA::API::PageOfComments;
use JIRA::API::PageOfDashboards;
use JIRA::API::PageOfStatuses;
use JIRA::API::PageOfWorklogs;
use JIRA::API::PagedListUserDetailsApplicationUser;
use JIRA::API::PaginatedResponseComment;
use JIRA::API::ParsedJqlQueries;
use JIRA::API::ParsedJqlQuery;
use JIRA::API::PermissionGrant;
use JIRA::API::PermissionGrants;
use JIRA::API::PermissionHolder;
use JIRA::API::PermissionScheme;
use JIRA::API::PermissionSchemes;
use JIRA::API::Permissions;
use JIRA::API::PermissionsKeysBean;
use JIRA::API::PermittedProjects;
use JIRA::API::Priority;
use JIRA::API::PriorityId;
use JIRA::API::Project;
use JIRA::API::ProjectAvatars;
use JIRA::API::ProjectCategory;
use JIRA::API::ProjectComponent;
use JIRA::API::ProjectDetails;
use JIRA::API::ProjectEmailAddress;
use JIRA::API::ProjectFeature;
use JIRA::API::ProjectFeatureState;
use JIRA::API::ProjectId;
use JIRA::API::ProjectIdentifierBean;
use JIRA::API::ProjectIdentifiers;
use JIRA::API::ProjectIds;
use JIRA::API::ProjectInsight;
use JIRA::API::ProjectIssueCreateMetadata;
use JIRA::API::ProjectIssueSecurityLevels;
use JIRA::API::ProjectIssueTypeHierarchy;
use JIRA::API::ProjectIssueTypeMapping;
use JIRA::API::ProjectIssueTypeMappings;
use JIRA::API::ProjectIssueTypes;
use JIRA::API::ProjectIssueTypesHierarchyLevel;
use JIRA::API::ProjectLandingPageInfo;
use JIRA::API::ProjectPermissions;
use JIRA::API::ProjectRole;
use JIRA::API::ProjectRoleActorsUpdateBean;
use JIRA::API::ProjectRoleDetails;
use JIRA::API::ProjectRoleGroup;
use JIRA::API::ProjectRoleUser;
use JIRA::API::ProjectScopeBean;
use JIRA::API::ProjectType;
use JIRA::API::PropertyKey;
use JIRA::API::PropertyKeys;
use JIRA::API::PublishDraftWorkflowScheme;
use JIRA::API::PublishedWorkflowId;
use JIRA::API::RegisteredWebhook;
use JIRA::API::RemoteIssueLink;
use JIRA::API::RemoteIssueLinkIdentifies;
use JIRA::API::RemoteIssueLinkRequest;
use JIRA::API::RemoteObject;
use JIRA::API::RemoveOptionFromIssuesResult;
use JIRA::API::ReorderIssuePriorities;
use JIRA::API::ReorderIssueResolutionsRequest;
use JIRA::API::Resolution;
use JIRA::API::ResolutionId;
use JIRA::API::ResolutionJsonBean;
use JIRA::API::RestrictedPermission;
use JIRA::API::RichText;
use JIRA::API::RoleActor;
use JIRA::API::RuleConfiguration;
use JIRA::API::SanitizedJqlQueries;
use JIRA::API::SanitizedJqlQuery;
use JIRA::API::Scope;
use JIRA::API::Screen;
use JIRA::API::ScreenDetails;
use JIRA::API::ScreenScheme;
use JIRA::API::ScreenSchemeDetails;
use JIRA::API::ScreenSchemeId;
use JIRA::API::ScreenTypes;
use JIRA::API::ScreenWithTab;
use JIRA::API::ScreenableField;
use JIRA::API::ScreenableTab;
use JIRA::API::SearchAutoCompleteFilter;
use JIRA::API::SearchRequestBean;
use JIRA::API::SearchResults;
use JIRA::API::SecurityLevel;
use JIRA::API::SecurityScheme;
use JIRA::API::SecuritySchemes;
use JIRA::API::ServerInformation;
use JIRA::API::ServiceManagementNavigationInfo;
use JIRA::API::SetDefaultPriorityRequest;
use JIRA::API::SetDefaultResolutionRequest;
use JIRA::API::SharePermission;
use JIRA::API::SharePermissionInputBean;
use JIRA::API::SimpleApplicationPropertyBean;
use JIRA::API::SimpleErrorCollection;
use JIRA::API::SimpleLink;
use JIRA::API::SimpleListWrapperApplicationRole;
use JIRA::API::SimpleListWrapperGroupName;
use JIRA::API::SimplifiedHierarchyLevel;
use JIRA::API::SoftwareNavigationInfo;
use JIRA::API::Status;
use JIRA::API::StatusCategory;
use JIRA::API::StatusCreate;
use JIRA::API::StatusCreateRequest;
use JIRA::API::StatusDetails;
use JIRA::API::StatusMapping;
use JIRA::API::StatusScope;
use JIRA::API::StatusUpdate;
use JIRA::API::StatusUpdateRequest;
use JIRA::API::StringList;
use JIRA::API::SuggestedIssue;
use JIRA::API::SystemAvatars;
use JIRA::API::TaskProgressBeanObject;
use JIRA::API::TaskProgressBeanRemoveOptionFromIssuesResult;
use JIRA::API::TimeTrackingConfiguration;
use JIRA::API::TimeTrackingDetails;
use JIRA::API::TimeTrackingProvider;
use JIRA::API::Transition;
use JIRA::API::TransitionScreenDetails;
use JIRA::API::Transitions;
use JIRA::API::UiModificationContextDetails;
use JIRA::API::UiModificationDetails;
use JIRA::API::UiModificationIdentifiers;
use JIRA::API::UnrestrictedUserEmail;
use JIRA::API::UpdateCustomFieldDetails;
use JIRA::API::UpdateDefaultScreenScheme;
use JIRA::API::UpdateFieldConfigurationSchemeDetails;
use JIRA::API::UpdateNotificationSchemeDetails;
use JIRA::API::UpdatePriorityDetails;
use JIRA::API::UpdateProjectDetails;
use JIRA::API::UpdateResolutionDetails;
use JIRA::API::UpdateScreenDetails;
use JIRA::API::UpdateScreenSchemeDetails;
use JIRA::API::UpdateScreenTypes;
use JIRA::API::UpdateUiModificationDetails;
use JIRA::API::UpdateUserToGroupBean;
use JIRA::API::UpdatedProjectCategory;
use JIRA::API::User;
use JIRA::API::UserBean;
use JIRA::API::UserBeanAvatarUrls;
use JIRA::API::UserContextVariable;
use JIRA::API::UserDetails;
use JIRA::API::UserFilter;
use JIRA::API::UserKey;
use JIRA::API::UserList;
use JIRA::API::UserMigrationBean;
use JIRA::API::UserPermission;
use JIRA::API::UserPickerUser;
use JIRA::API::ValueOperand;
use JIRA::API::Version;
use JIRA::API::VersionIssueCounts;
use JIRA::API::VersionIssuesStatus;
use JIRA::API::VersionMoveBean;
use JIRA::API::VersionUnresolvedIssuesCount;
use JIRA::API::VersionUsageInCustomField;
use JIRA::API::Visibility;
use JIRA::API::Votes;
use JIRA::API::WarningCollection;
use JIRA::API::Watchers;
use JIRA::API::Webhook;
use JIRA::API::WebhookDetails;
use JIRA::API::WebhookRegistrationDetails;
use JIRA::API::WebhooksExpirationDate;
use JIRA::API::WorkManagementNavigationInfo;
use JIRA::API::Workflow;
use JIRA::API::WorkflowCompoundCondition;
use JIRA::API::WorkflowCondition;
use JIRA::API::WorkflowIDs;
use JIRA::API::WorkflowId;
use JIRA::API::WorkflowOperations;
use JIRA::API::WorkflowRules;
use JIRA::API::WorkflowRulesSearch;
use JIRA::API::WorkflowRulesSearchDetails;
use JIRA::API::WorkflowScheme;
use JIRA::API::WorkflowSchemeAssociations;
use JIRA::API::WorkflowSchemeIdName;
use JIRA::API::WorkflowSchemeProjectAssociation;
use JIRA::API::WorkflowSimpleCondition;
use JIRA::API::WorkflowStatus;
use JIRA::API::WorkflowTransition;
use JIRA::API::WorkflowTransitionProperty;
use JIRA::API::WorkflowTransitionRule;
use JIRA::API::WorkflowTransitionRules;
use JIRA::API::WorkflowTransitionRulesDetails;
use JIRA::API::WorkflowTransitionRulesUpdate;
use JIRA::API::WorkflowTransitionRulesUpdateErrorDetails;
use JIRA::API::WorkflowTransitionRulesUpdateErrors;
use JIRA::API::WorkflowsWithTransitionRulesDetails;
use JIRA::API::Worklog;
use JIRA::API::WorklogIdsRequestBean;

=head1 SYNOPSIS

=head1 PROPERTIES

=head2 B<< openapi >>

=head2 B<< ua >>

=head2 B<< server >>

=cut

# XXX this should be more configurable, and potentially you don't want validation?!
has 'schema' => (
    is => 'lazy',
    default => sub {
        YAML::PP->new( boolean => 'JSON::PP' )->load_file( 'ollama/ollama-curated.yaml' );
    },
);

has 'openapi' => (
    is => 'lazy',
    default => sub { OpenAPI::Modern->new( openapi_schema => $_[0]->schema, openapi_uri => '/api' )},
);

# The HTTP stuff should go into a ::Role I guess
has 'ua' => (
    is => 'lazy',
    default => sub { Mojo::UserAgent->new },
);

has 'server' => (
    is => 'lazy',
    default => sub { 'http://localhost:11434/api' }, # XXX pull from OpenAPI file instead
);

=head1 METHODS

=head2 C<< getBanner >>

  my $res = $client->getBanner()->get;

Get announcement banner configuration

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::AnnouncementBannerConfiguration >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getBanner_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/announcementBanner';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getBanner( $self, %options ) {
    my $tx = $self->_build_getBanner_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AnnouncementBannerConfiguration->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setBanner >>

  my $res = $client->setBanner()->get;

Update announcement banner configuration

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< isDismissible >>

Flag indicating if the announcement banner can be dismissed by the user.

=item C<< isEnabled >>

Flag indicating if the announcement banner is enabled or not.

=item C<< message >>

The text on the announcement banner.

=item C<< visibility >>

Visibility of the announcement banner. Can be public or private.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_setBanner_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/announcementBanner';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::AnnouncementBannerConfigurationUpdate->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setBanner( $self, %options ) {
    my $tx = $self->_build_setBanner_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if an invalid parameter is passed.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateMultipleCustomFieldValues >>

  my $res = $client->updateMultipleCustomFieldValues()->get;

Update custom fields

=head3 Parameters

=over 4

=item B<< generateChangelog >>

Whether to generate a changelog for this update.

=back


=head3 Options

=over 4

=item C<< updates >>

=back

Returns a L<<  >>.

=cut

sub _build_updateMultipleCustomFieldValues_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/app/field/value';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'generateChangelog' => delete $options{'generateChangelog'},
    );

    my $request = JIRA::API::MultipleCustomFieldValuesUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateMultipleCustomFieldValues( $self, %options ) {
    my $tx = $self->_build_updateMultipleCustomFieldValues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as the app that provided all the fields.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCustomFieldConfiguration >>

  my $res = $client->getCustomFieldConfiguration()->get;

Get custom field configurations

=head3 Parameters

=over 4

=item B<< fieldIdOrKey >>

The ID or key of the custom field, for example C<customfield_10000>.

=item B<< id >>

The list of configuration IDs. To include multiple configurations, separate IDs with an ampersand: C<id=10000&id=10001>. Can't be provided with C<fieldContextId>, C<issueId>, C<projectKeyOrId>, or C<issueTypeId>.

=item B<< fieldContextId >>

The list of field context IDs. To include multiple field contexts, separate IDs with an ampersand: C<fieldContextId=10000&fieldContextId=10001>. Can't be provided with C<id>, C<issueId>, C<projectKeyOrId>, or C<issueTypeId>.

=item B<< issueId >>

The ID of the issue to filter results by. If the issue doesn't exist, an empty list is returned. Can't be provided with C<projectKeyOrId>, or C<issueTypeId>.

=item B<< projectKeyOrId >>

The ID or key of the project to filter results by. Must be provided with C<issueTypeId>. Can't be provided with C<issueId>.

=item B<< issueTypeId >>

The ID of the issue type to filter results by. Must be provided with C<projectKeyOrId>. Can't be provided with C<issueId>.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanContextualConfiguration >>.

=cut

sub _build_getCustomFieldConfiguration_request( $self, %options ) {
    croak "Missing required parameter 'fieldIdOrKey'"
        unless exists $options{ 'fieldIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/app/field/{fieldIdOrKey}/context/configuration' );
    my $path = $template->process(
              'fieldIdOrKey' => delete $options{'fieldIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'id' => delete $options{'id'},
        maybe 'fieldContextId' => delete $options{'fieldContextId'},
        maybe 'issueId' => delete $options{'issueId'},
        maybe 'projectKeyOrId' => delete $options{'projectKeyOrId'},
        maybe 'issueTypeId' => delete $options{'issueTypeId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getCustomFieldConfiguration( $self, %options ) {
    my $tx = $self->_build_getCustomFieldConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanContextualConfiguration->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not a Jira admin or the request is not authenticated as from the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateCustomFieldConfiguration >>

  my $res = $client->updateCustomFieldConfiguration()->get;

Update custom field configurations

=head3 Parameters

=over 4

=item B<< fieldIdOrKey >>

The ID or key of the custom field, for example C<customfield_10000>.

=back


=head3 Options

=over 4

=item C<< configurations >>

The list of custom field configuration details.

=back

Returns a L<<  >>.

=cut

sub _build_updateCustomFieldConfiguration_request( $self, %options ) {
    croak "Missing required parameter 'fieldIdOrKey'"
        unless exists $options{ 'fieldIdOrKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/app/field/{fieldIdOrKey}/context/configuration' );
    my $path = $template->process(
              'fieldIdOrKey' => delete $options{'fieldIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CustomFieldConfigurations->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateCustomFieldConfiguration( $self, %options ) {
    my $tx = $self->_build_updateCustomFieldConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not a Jira admin or the request is not authenticated as from the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateCustomFieldValue >>

  my $res = $client->updateCustomFieldValue()->get;

Update custom field value

=head3 Parameters

=over 4

=item B<< fieldIdOrKey >>

The ID or key of the custom field. For example, C<customfield_10010>.

=item B<< generateChangelog >>

Whether to generate a changelog for this update.

=back


=head3 Options

=over 4

=item C<< updates >>

The list of custom field update details.

=back

Returns a L<<  >>.

=cut

sub _build_updateCustomFieldValue_request( $self, %options ) {
    croak "Missing required parameter 'fieldIdOrKey'"
        unless exists $options{ 'fieldIdOrKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/app/field/{fieldIdOrKey}/value' );
    my $path = $template->process(
              'fieldIdOrKey' => delete $options{'fieldIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'generateChangelog' => delete $options{'generateChangelog'},
    );

    my $request = JIRA::API::CustomFieldValueUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateCustomFieldValue( $self, %options ) {
    my $tx = $self->_build_updateCustomFieldValue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getApplicationProperty >>

  my $res = $client->getApplicationProperty()->get;

Get application property

=head3 Parameters

=over 4

=item B<< key >>

The key of the application property.

=item B<< permissionLevel >>

The permission level of all items being returned in the list.

=item B<< keyFilter >>

When a C<key> isn't provided, this filters the list of results by the application property C<key> using a regular expression. For example, using C<jira.lf.*> will return all application properties with keys that start with I<jira.lf.>.

=back


Returns an array of L<< JIRA::API::ApplicationProperty >>.

=cut

sub _build_getApplicationProperty_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/application-properties';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'key' => delete $options{'key'},
        maybe 'permissionLevel' => delete $options{'permissionLevel'},
        maybe 'keyFilter' => delete $options{'keyFilter'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getApplicationProperty( $self, %options ) {
    my $tx = $self->_build_getApplicationProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ApplicationProperty->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the application property is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAdvancedSettings >>

  my $res = $client->getAdvancedSettings()->get;

Get advanced settings

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ApplicationProperty >>.

=cut

sub _build_getAdvancedSettings_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/application-properties/advanced-settings';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAdvancedSettings( $self, %options ) {
    my $tx = $self->_build_getAdvancedSettings_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ApplicationProperty->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not an administrator.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setApplicationProperty >>

  my $res = $client->setApplicationProperty()->get;

Set application property

=head3 Parameters

=over 4

=item B<< id >>

The key of the application property to update.

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the application property.

=item C<< value >>

The new value.

=back

Returns a L<< JIRA::API::ApplicationProperty >>.

=cut

sub _build_setApplicationProperty_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/application-properties/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::SimpleApplicationPropertyBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setApplicationProperty( $self, %options ) {
    my $tx = $self->_build_setApplicationProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ApplicationProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the data type of the `value` does not match the application property's data type. For example, a string is provided instead of an integer.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to edit the property.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the property is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllApplicationRoles >>

  my $res = $client->getAllApplicationRoles()->get;

Get all application roles

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ApplicationRole >>.

=cut

sub _build_getAllApplicationRoles_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/applicationrole';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllApplicationRoles( $self, %options ) {
    my $tx = $self->_build_getAllApplicationRoles_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ApplicationRole->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not an administrator.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getApplicationRole >>

  my $res = $client->getApplicationRole()->get;

Get application role

=head3 Parameters

=over 4

=item B<< key >>

The key of the application role. Use the L<Get all application roles|#api-rest-api-3-applicationrole-get> operation to get the key for each application role.

=back


Returns a L<< JIRA::API::ApplicationRole >>.

=cut

sub _build_getApplicationRole_request( $self, %options ) {
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/applicationrole/{key}' );
    my $path = $template->process(
              'key' => delete $options{'key'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getApplicationRole( $self, %options ) {
    my $tx = $self->_build_getApplicationRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ApplicationRole->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not an administrator.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAttachmentContent >>

  my $res = $client->getAttachmentContent()->get;

Get attachment content

=head3 Parameters

=over 4

=item B<< id >>

The ID of the attachment.

=item B<< redirect >>

Whether a redirect is provided for the attachment download. Clients that do not automatically follow redirects can set this to C<false> to avoid making multiple requests to download the attachment.

=back


Returns a L<< object >>.

=cut

sub _build_getAttachmentContent_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/attachment/content/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'redirect' => delete $options{'redirect'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAttachmentContent( $self, %options ) {
    my $tx = $self->_build_getAttachmentContent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful when `redirect` is set to `false`.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 206 ) {
            # Returned if the request is successful when a `Range` header is provided and `redirect` is set to `false`.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 303 ) {
            # Returned if the request is successful. See the `Location` header for the download URL.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the range supplied in the `Range` header is malformed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # The user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the attachment is not found. * attachments are disabled in the Jira settings.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 416 ) {
            # Returned if the server is unable to satisfy the range of bytes provided.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAttachmentMeta >>

  my $res = $client->getAttachmentMeta()->get;

Get Jira attachment settings

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::AttachmentSettings >>.

=cut

sub _build_getAttachmentMeta_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/attachment/meta';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAttachmentMeta( $self, %options ) {
    my $tx = $self->_build_getAttachmentMeta_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AttachmentSettings->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAttachmentThumbnail >>

  my $res = $client->getAttachmentThumbnail()->get;

Get attachment thumbnail

=head3 Parameters

=over 4

=item B<< id >>

The ID of the attachment.

=item B<< redirect >>

Whether a redirect is provided for the attachment download. Clients that do not automatically follow redirects can set this to C<false> to avoid making multiple requests to download the attachment.

=item B<< fallbackToDefault >>

Whether a default thumbnail is returned when the requested thumbnail is not found.

=item B<< width >>

The maximum width to scale the thumbnail to.

=item B<< height >>

The maximum height to scale the thumbnail to.

=back


Returns a L<< object >>.

=cut

sub _build_getAttachmentThumbnail_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/attachment/thumbnail/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'redirect' => delete $options{'redirect'},
        maybe 'fallbackToDefault' => delete $options{'fallbackToDefault'},
        maybe 'width' => delete $options{'width'},
        maybe 'height' => delete $options{'height'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAttachmentThumbnail( $self, %options ) {
    my $tx = $self->_build_getAttachmentThumbnail_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful when `redirect` is set to `false`.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 303 ) {
            # Returned if the request is successful. See the `Location` header for the download URL.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # The user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the attachment is not found. * attachments are disabled in the Jira settings. * `fallbackToDefault` is `false` and the request thumbnail cannot be downloaded.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeAttachment >>

  my $res = $client->removeAttachment()->get;

Delete attachment

=head3 Parameters

=over 4

=item B<< id >>

The ID of the attachment.

=back



=cut

sub _build_removeAttachment_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/attachment/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeAttachment( $self, %options ) {
    my $tx = $self->_build_removeAttachment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the attachment is not found. * attachments are disabled in the Jira settings.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAttachment >>

  my $res = $client->getAttachment()->get;

Get attachment metadata

=head3 Parameters

=over 4

=item B<< id >>

The ID of the attachment.

=back


Returns a L<< JIRA::API::AttachmentMetadata >>.

=cut

sub _build_getAttachment_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/attachment/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAttachment( $self, %options ) {
    my $tx = $self->_build_getAttachment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AttachmentMetadata->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the attachment is not found. * attachments are disabled in the Jira settings.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< expandAttachmentForHumans >>

  my $res = $client->expandAttachmentForHumans()->get;

Get all metadata for an expanded attachment

=head3 Parameters

=over 4

=item B<< id >>

The ID of the attachment.

=back


Returns a L<< JIRA::API::AttachmentArchiveMetadataReadable >>.

=cut

sub _build_expandAttachmentForHumans_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/attachment/{id}/expand/human' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub expandAttachmentForHumans( $self, %options ) {
    my $tx = $self->_build_expandAttachmentForHumans_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful. If an empty list is returned in the response, the attachment is empty, corrupt, or not an archive.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AttachmentArchiveMetadataReadable->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # The user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the attachment is not found. * attachments are disabled in the Jira settings.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the attachment is an archive, but not a supported archive format.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< expandAttachmentForMachines >>

  my $res = $client->expandAttachmentForMachines()->get;

Get contents metadata for an expanded attachment

=head3 Parameters

=over 4

=item B<< id >>

The ID of the attachment.

=back


Returns a L<< JIRA::API::AttachmentArchiveImpl >>.

=cut

sub _build_expandAttachmentForMachines_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/attachment/{id}/expand/raw' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub expandAttachmentForMachines( $self, %options ) {
    my $tx = $self->_build_expandAttachmentForMachines_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful. If an empty list is returned in the response, the attachment is empty, corrupt, or not an archive.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AttachmentArchiveImpl->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # The user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the attachment is not found. * attachments are disabled in the Jira settings.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the attachment is an archive, but not a supported archive format.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAuditRecords >>

  my $res = $client->getAuditRecords()->get;

Get audit records

=head3 Parameters

=over 4

=item B<< offset >>

The number of records to skip before returning the first result.

=item B<< limit >>

The maximum number of results to return.

=item B<< filter >>

The strings to match with audit field content, space separated.

=item B<< from >>

The date and time on or after which returned audit records must have been created. If C<to> is provided C<from> must be before C<to> or no audit records are returned.

=item B<< to >>

The date and time on or before which returned audit results must have been created. If C<from> is provided C<to> must be after C<from> or no audit records are returned.

=back


Returns a L<< JIRA::API::AuditRecords >>.

=cut

sub _build_getAuditRecords_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/auditing/record';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'offset' => delete $options{'offset'},
        maybe 'limit' => delete $options{'limit'},
        maybe 'filter' => delete $options{'filter'},
        maybe 'from' => delete $options{'from'},
        maybe 'to' => delete $options{'to'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAuditRecords( $self, %options ) {
    my $tx = $self->_build_getAuditRecords_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AuditRecords->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if: * the user does not have the required permissions. * all Jira products are on free plans. Audit logs are available when at least one Jira product is on a paid plan.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllSystemAvatars >>

  my $res = $client->getAllSystemAvatars()->get;

Get system avatars by type

=head3 Parameters

=over 4

=item B<< type >>

The avatar type.

=back


Returns a L<< JIRA::API::SystemAvatars >>.

=cut

sub _build_getAllSystemAvatars_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/avatar/{type}/system' );
    my $path = $template->process(
              'type' => delete $options{'type'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllSystemAvatars( $self, %options ) {
    my $tx = $self->_build_getAllSystemAvatars_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SystemAvatars->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 500 ) {
            # Returned if an error occurs while retrieving the list of avatars.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCommentsByIds >>

  my $res = $client->getCommentsByIds()->get;

Get comments by IDs

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about comments in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<renderedBody> Returns the comment body rendered in HTML.


=item *

C<properties> Returns the comment's properties.


=back

=back


=head3 Options

=over 4

=item C<< ids >>

The list of comment IDs. A maximum of 1000 IDs can be specified.

=back

Returns a L<< JIRA::API::PageBeanComment >>.

=cut

sub _build_getCommentsByIds_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/comment/list';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::IssueCommentListRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getCommentsByIds( $self, %options ) {
    my $tx = $self->_build_getCommentsByIds_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanComment->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request contains more than 1000 IDs or is empty.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCommentPropertyKeys >>

  my $res = $client->getCommentPropertyKeys()->get;

Get comment property keys

=head3 Parameters

=over 4

=item B<< commentId >>

The ID of the comment.

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getCommentPropertyKeys_request( $self, %options ) {
    croak "Missing required parameter 'commentId'"
        unless exists $options{ 'commentId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/comment/{commentId}/properties' );
    my $path = $template->process(
              'commentId' => delete $options{'commentId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getCommentPropertyKeys( $self, %options ) {
    my $tx = $self->_build_getCommentPropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the comment ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the comment is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteCommentProperty >>

  my $res = $client->deleteCommentProperty()->get;

Delete comment property

=head3 Parameters

=over 4

=item B<< commentId >>

The ID of the comment.

=item B<< propertyKey >>

The key of the property.

=back



=cut

sub _build_deleteCommentProperty_request( $self, %options ) {
    croak "Missing required parameter 'commentId'"
        unless exists $options{ 'commentId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/comment/{commentId}/properties/{propertyKey}' );
    my $path = $template->process(
              'commentId' => delete $options{'commentId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteCommentProperty( $self, %options ) {
    my $tx = $self->_build_deleteCommentProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the comment or the property is not found or the user has the necessary project permissions but isn't a member of the role or group visibility of the comment is restricted to.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCommentProperty >>

  my $res = $client->getCommentProperty()->get;

Get comment property

=head3 Parameters

=over 4

=item B<< commentId >>

The ID of the comment.

=item B<< propertyKey >>

The key of the property.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getCommentProperty_request( $self, %options ) {
    croak "Missing required parameter 'commentId'"
        unless exists $options{ 'commentId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/comment/{commentId}/properties/{propertyKey}' );
    my $path = $template->process(
              'commentId' => delete $options{'commentId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getCommentProperty( $self, %options ) {
    my $tx = $self->_build_getCommentProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the comment or the property is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setCommentProperty >>

  my $res = $client->setCommentProperty()->get;

Set comment property

=head3 Parameters

=over 4

=item B<< commentId >>

The ID of the comment.

=item B<< propertyKey >>

The key of the property. The maximum length is 255 characters.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setCommentProperty_request( $self, %options ) {
    croak "Missing required parameter 'commentId'"
        unless exists $options{ 'commentId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/comment/{commentId}/properties/{propertyKey}' );
    my $path = $template->process(
              'commentId' => delete $options{'commentId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setCommentProperty( $self, %options ) {
    my $tx = $self->_build_setCommentProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the comment property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the comment property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the comment is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createComponent >>

  my $res = $client->createComponent()->get;

Create component

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< assignee >>

The details of the user associated with C<assigneeType>, if any. See C<realAssignee> for details of the user assigned to issues created with this component.

=item C<< assigneeType >>

The nominal user type used to determine the assignee for issues created with this component. See C<realAssigneeType> for details on how the type of the user, and hence the user, assigned to issues is determined. Can take the following values:

=over

=item *

C<PROJECT_LEAD> the assignee to any issues created with this component is nominally the lead for the project the component is in.


=item *

C<COMPONENT_LEAD> the assignee to any issues created with this component is nominally the lead for the component.


=item *

C<UNASSIGNED> an assignee is not set for issues created with this component.


=item *

C<PROJECT_DEFAULT> the assignee to any issues created with this component is nominally the default assignee for the project that the component is in.


=back

Default value: C<PROJECT_DEFAULT>.

Optional when creating or updating a component.

=item C<< description >>

The description for the component. Optional when creating or updating a component.

=item C<< id >>

The unique identifier for the component.

=item C<< isAssigneeTypeValid >>

Whether a user is associated with C<assigneeType>. For example, if the C<assigneeType> is set to C<COMPONENT_LEAD> but the component lead is not set, then C<false> is returned.

=item C<< lead >>

The user details for the component's lead user.

=item C<< leadAccountId >>

The accountId of the component's lead user. The accountId uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item C<< leadUserName >>

This property is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item C<< name >>

The unique name for the component in the project. Required when creating a component. Optional when updating a component. The maximum length is 255 characters.

=item C<< project >>

The key of the project the component is assigned to. Required when creating a component. Can't be updated.

=item C<< projectId >>

The ID of the project the component is assigned to.

=item C<< realAssignee >>

The user assigned to issues created with this component, when C<assigneeType> does not identify a valid assignee.

=item C<< realAssigneeType >>

The type of the assignee that is assigned to issues created with this component, when an assignee cannot be set from the C<assigneeType>. For example, C<assigneeType> is set to C<COMPONENT_LEAD> but no component lead is set. This property is set to one of the following values:

=over

=item *

C<PROJECT_LEAD> when C<assigneeType> is C<PROJECT_LEAD> and the project lead has permission to be assigned issues in the project that the component is in.


=item *

C<COMPONENT_LEAD> when C<assignee>Type is C<COMPONENT_LEAD> and the component lead has permission to be assigned issues in the project that the component is in.


=item *

C<UNASSIGNED> when C<assigneeType> is C<UNASSIGNED> and Jira is configured to allow unassigned issues.


=item *

C<PROJECT_DEFAULT> when none of the preceding cases are true.


=back

=item C<< self >>

The URL of the component.

=back

Returns a L<< JIRA::API::ProjectComponent >>.

=cut

sub _build_createComponent_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/component';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectComponent->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createComponent( $self, %options ) {
    my $tx = $self->_build_createComponent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectComponent->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the user is not found. * `name` is not provided. * `name` is over 255 characters in length. * `projectId` is not provided. * `assigneeType` is an invalid value.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to manage the project containing the component or does not have permission to administer Jira.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to browse the project containing the component.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteComponent >>

  my $res = $client->deleteComponent()->get;

Delete component

=head3 Parameters

=over 4

=item B<< id >>

The ID of the component.

=item B<< moveIssuesTo >>

The ID of the component to replace the deleted component. If this value is null no replacement is made.

=back



=cut

sub _build_deleteComponent_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/component/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'moveIssuesTo' => delete $options{'moveIssuesTo'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteComponent( $self, %options ) {
    my $tx = $self->_build_deleteComponent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to manage the project containing the component or does not have permission to administer Jira.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the component is not found. * the replacement component is not found. * the user does not have permission to browse the project containing the component.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getComponent >>

  my $res = $client->getComponent()->get;

Get component

=head3 Parameters

=over 4

=item B<< id >>

The ID of the component.

=back


Returns a L<< JIRA::API::ProjectComponent >>.

=cut

sub _build_getComponent_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/component/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getComponent( $self, %options ) {
    my $tx = $self->_build_getComponent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectComponent->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the component is not found or the user does not have permission to browse the project containing the component.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateComponent >>

  my $res = $client->updateComponent()->get;

Update component

=head3 Parameters

=over 4

=item B<< id >>

The ID of the component.

=back


=head3 Options

=over 4

=item C<< assignee >>

The details of the user associated with C<assigneeType>, if any. See C<realAssignee> for details of the user assigned to issues created with this component.

=item C<< assigneeType >>

The nominal user type used to determine the assignee for issues created with this component. See C<realAssigneeType> for details on how the type of the user, and hence the user, assigned to issues is determined. Can take the following values:

=over

=item *

C<PROJECT_LEAD> the assignee to any issues created with this component is nominally the lead for the project the component is in.


=item *

C<COMPONENT_LEAD> the assignee to any issues created with this component is nominally the lead for the component.


=item *

C<UNASSIGNED> an assignee is not set for issues created with this component.


=item *

C<PROJECT_DEFAULT> the assignee to any issues created with this component is nominally the default assignee for the project that the component is in.


=back

Default value: C<PROJECT_DEFAULT>.

Optional when creating or updating a component.

=item C<< description >>

The description for the component. Optional when creating or updating a component.

=item C<< id >>

The unique identifier for the component.

=item C<< isAssigneeTypeValid >>

Whether a user is associated with C<assigneeType>. For example, if the C<assigneeType> is set to C<COMPONENT_LEAD> but the component lead is not set, then C<false> is returned.

=item C<< lead >>

The user details for the component's lead user.

=item C<< leadAccountId >>

The accountId of the component's lead user. The accountId uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item C<< leadUserName >>

This property is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item C<< name >>

The unique name for the component in the project. Required when creating a component. Optional when updating a component. The maximum length is 255 characters.

=item C<< project >>

The key of the project the component is assigned to. Required when creating a component. Can't be updated.

=item C<< projectId >>

The ID of the project the component is assigned to.

=item C<< realAssignee >>

The user assigned to issues created with this component, when C<assigneeType> does not identify a valid assignee.

=item C<< realAssigneeType >>

The type of the assignee that is assigned to issues created with this component, when an assignee cannot be set from the C<assigneeType>. For example, C<assigneeType> is set to C<COMPONENT_LEAD> but no component lead is set. This property is set to one of the following values:

=over

=item *

C<PROJECT_LEAD> when C<assigneeType> is C<PROJECT_LEAD> and the project lead has permission to be assigned issues in the project that the component is in.


=item *

C<COMPONENT_LEAD> when C<assignee>Type is C<COMPONENT_LEAD> and the component lead has permission to be assigned issues in the project that the component is in.


=item *

C<UNASSIGNED> when C<assigneeType> is C<UNASSIGNED> and Jira is configured to allow unassigned issues.


=item *

C<PROJECT_DEFAULT> when none of the preceding cases are true.


=back

=item C<< self >>

The URL of the component.

=back

Returns a L<< JIRA::API::ProjectComponent >>.

=cut

sub _build_updateComponent_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/component/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectComponent->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateComponent( $self, %options ) {
    my $tx = $self->_build_updateComponent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectComponent->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the user is not found. * `assigneeType` is an invalid value. * `name` is over 255 characters in length.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to manage the project containing the component or does not have permission to administer Jira.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the component is not found or the user does not have permission to browse the project containing the component.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getComponentRelatedIssues >>

  my $res = $client->getComponentRelatedIssues()->get;

Get component issues count

=head3 Parameters

=over 4

=item B<< id >>

The ID of the component.

=back


Returns a L<< JIRA::API::ComponentIssuesCount >>.

=cut

sub _build_getComponentRelatedIssues_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/component/{id}/relatedIssueCounts' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getComponentRelatedIssues( $self, %options ) {
    my $tx = $self->_build_getComponentRelatedIssues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ComponentIssuesCount->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the component is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getConfiguration >>

  my $res = $client->getConfiguration()->get;

Get global settings

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::Configuration >>.

=cut

sub _build_getConfiguration_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/configuration';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getConfiguration( $self, %options ) {
    my $tx = $self->_build_getConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Configuration->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getSelectedTimeTrackingImplementation >>

  my $res = $client->getSelectedTimeTrackingImplementation()->get;

Get selected time tracking provider

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::TimeTrackingProvider >>.
Returns a L<<  >>.

=cut

sub _build_getSelectedTimeTrackingImplementation_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/configuration/timetracking';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getSelectedTimeTrackingImplementation( $self, %options ) {
    my $tx = $self->_build_getSelectedTimeTrackingImplementation_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful and time tracking is enabled.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TimeTrackingProvider->new($payload),

                );
            }
        } elsif( $resp->code == 204 ) {
            # Returned if the request is successful but time tracking is disabled.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< selectTimeTrackingImplementation >>

  my $res = $client->selectTimeTrackingImplementation()->get;

Select time tracking provider

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< key >>

The key for the time tracking provider. For example, I<JIRA>.

=item C<< name >>

The name of the time tracking provider. For example, I<JIRA provided time tracking>.

=item C<< url >>

The URL of the configuration page for the time tracking provider app. For example, I</example/config/url>. This property is only returned if the C<adminPageKey> property is set in the module descriptor of the time tracking provider app.

=back

Returns a L<<  >>.

=cut

sub _build_selectTimeTrackingImplementation_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/configuration/timetracking';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::TimeTrackingProvider->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub selectTimeTrackingImplementation( $self, %options ) {
    my $tx = $self->_build_selectTimeTrackingImplementation_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the time tracking provider is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAvailableTimeTrackingImplementations >>

  my $res = $client->getAvailableTimeTrackingImplementations()->get;

Get all time tracking providers

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::TimeTrackingProvider >>.

=cut

sub _build_getAvailableTimeTrackingImplementations_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/configuration/timetracking/list';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAvailableTimeTrackingImplementations( $self, %options ) {
    my $tx = $self->_build_getAvailableTimeTrackingImplementations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::TimeTrackingProvider->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getSharedTimeTrackingConfiguration >>

  my $res = $client->getSharedTimeTrackingConfiguration()->get;

Get time tracking settings

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::TimeTrackingConfiguration >>.

=cut

sub _build_getSharedTimeTrackingConfiguration_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/configuration/timetracking/options';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getSharedTimeTrackingConfiguration( $self, %options ) {
    my $tx = $self->_build_getSharedTimeTrackingConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TimeTrackingConfiguration->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setSharedTimeTrackingConfiguration >>

  my $res = $client->setSharedTimeTrackingConfiguration()->get;

Set time tracking settings

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< defaultUnit >>

The default unit of time applied to logged time.

=item C<< timeFormat >>

The format that will appear on an issue's I<Time Spent> field.

=item C<< workingDaysPerWeek >>

The number of days in a working week.

=item C<< workingHoursPerDay >>

The number of hours in a working day.

=back

Returns a L<< JIRA::API::TimeTrackingConfiguration >>.

=cut

sub _build_setSharedTimeTrackingConfiguration_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/configuration/timetracking/options';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::TimeTrackingConfiguration->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setSharedTimeTrackingConfiguration( $self, %options ) {
    my $tx = $self->_build_setSharedTimeTrackingConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TimeTrackingConfiguration->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request object is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCustomFieldOption >>

  my $res = $client->getCustomFieldOption()->get;

Get custom field option

=head3 Parameters

=over 4

=item B<< id >>

The ID of the custom field option.

=back


Returns a L<< JIRA::API::CustomFieldOption >>.

=cut

sub _build_getCustomFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/customFieldOption/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getCustomFieldOption( $self, %options ) {
    my $tx = $self->_build_getCustomFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CustomFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the custom field option is not found. * the user does not have permission to view the custom field.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllDashboards >>

  my $res = $client->getAllDashboards()->get;

Get all dashboards

=head3 Parameters

=over 4

=item B<< filter >>

The filter applied to the list of dashboards. Valid values are:

=over

=item *

C<favourite> Returns dashboards the user has marked as favorite.


=item *

C<my> Returns dashboards owned by the user.


=back

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageOfDashboards >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getAllDashboards_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/dashboard';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'filter' => delete $options{'filter'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllDashboards( $self, %options ) {
    my $tx = $self->_build_getAllDashboards_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageOfDashboards->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createDashboard >>

  my $res = $client->createDashboard()->get;

Create dashboard

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the dashboard.

=item C<< editPermissions >>

The edit permissions for the dashboard.

=item C<< name >>

The name of the dashboard.

=item C<< sharePermissions >>

The share permissions for the dashboard.

=back

Returns a L<< JIRA::API::Dashboard >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_createDashboard_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/dashboard';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DashboardDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createDashboard( $self, %options ) {
    my $tx = $self->_build_createDashboard_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Dashboard->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllAvailableDashboardGadgets >>

  my $res = $client->getAllAvailableDashboardGadgets()->get;

Get available gadgets

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::AvailableDashboardGadgetsResponse >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getAllAvailableDashboardGadgets_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/dashboard/gadgets';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllAvailableDashboardGadgets( $self, %options ) {
    my $tx = $self->_build_getAllAvailableDashboardGadgets_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AvailableDashboardGadgetsResponse->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # 400 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDashboardsPaginated >>

  my $res = $client->getDashboardsPaginated()->get;

Search for dashboards

=head3 Parameters

=over 4

=item B<< dashboardName >>

String used to perform a case-insensitive partial match with C<name>.

=item B<< accountId >>

User account ID used to return dashboards with the matching C<owner.accountId>. This parameter cannot be used with the C<owner> parameter.

=item B<< owner >>

This parameter is deprecated because of privacy changes. Use C<accountId> instead. See the L<migration guide|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details. User name used to return dashboards with the matching C<owner.name>. This parameter cannot be used with the C<accountId> parameter.

=item B<< groupname >>

As a group's name can change, use of C<groupId> is recommended. Group name used to return dashboards that are shared with a group that matches C<sharePermissions.group.name>. This parameter cannot be used with the C<groupId> parameter.

=item B<< groupId >>

Group ID used to return dashboards that are shared with a group that matches C<sharePermissions.group.groupId>. This parameter cannot be used with the C<groupname> parameter.

=item B<< projectId >>

Project ID used to returns dashboards that are shared with a project that matches C<sharePermissions.project.id>.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<description> Sorts by dashboard description. Note that this sort works independently of whether the expand to display the description field is in use.


=item *

C<favourite_count> Sorts by dashboard popularity.


=item *

C<id> Sorts by dashboard ID.


=item *

C<is_favourite> Sorts by whether the dashboard is marked as a favorite.


=item *

C<name> Sorts by dashboard name.


=item *

C<owner> Sorts by dashboard owner name.


=back

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< status >>

The status to filter by. It may be active, archived or deleted.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about dashboard in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<description> Returns the description of the dashboard.


=item *

C<owner> Returns the owner of the dashboard.


=item *

C<viewUrl> Returns the URL that is used to view the dashboard.


=item *

C<favourite> Returns C<isFavourite>, an indicator of whether the user has set the dashboard as a favorite.


=item *

C<favouritedCount> Returns C<popularity>, a count of how many users have set this dashboard as a favorite.


=item *

C<sharePermissions> Returns details of the share permissions defined for the dashboard.


=item *

C<editPermissions> Returns details of the edit permissions defined for the dashboard.


=item *

C<isWritable> Returns whether the current user has permission to edit the dashboard.


=back

=back


Returns a L<< JIRA::API::PageBeanDashboard >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getDashboardsPaginated_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/dashboard/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'dashboardName' => delete $options{'dashboardName'},
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'owner' => delete $options{'owner'},
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'projectId' => delete $options{'projectId'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'status' => delete $options{'status'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDashboardsPaginated( $self, %options ) {
    my $tx = $self->_build_getDashboardsPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanDashboard->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `orderBy` is invalid. * `expand` includes an invalid value. * `accountId` and `owner` are provided. * `groupname` and `groupId` are provided.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # 401 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllGadgets >>

  my $res = $client->getAllGadgets()->get;

Get gadgets

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< moduleKey >>

The list of gadgets module keys. To include multiple module keys, separate module keys with ampersand: C<moduleKey=key:one&moduleKey=key:two>.

=item B<< uri >>

The list of gadgets URIs. To include multiple URIs, separate URIs with ampersand: C<uri=/rest/example/uri/1&uri=/rest/example/uri/2>.

=item B<< gadgetId >>

The list of gadgets IDs. To include multiple IDs, separate IDs with ampersand: C<gadgetId=10000&gadgetId=10001>.

=back


Returns a L<< JIRA::API::DashboardGadgetResponse >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getAllGadgets_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/gadget' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'moduleKey' => delete $options{'moduleKey'},
        maybe 'uri' => delete $options{'uri'},
        maybe 'gadgetId' => delete $options{'gadgetId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllGadgets( $self, %options ) {
    my $tx = $self->_build_getAllGadgets_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::DashboardGadgetResponse->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addGadget >>

  my $res = $client->addGadget()->get;

Add gadget to dashboard

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=back


=head3 Options

=over 4

=item C<< color >>

The color of the gadget. Should be one of C<blue>, C<red>, C<yellow>, C<green>, C<cyan>, C<purple>, C<gray>, or C<white>.

=item C<< ignoreUriAndModuleKeyValidation >>

Whether to ignore the validation of module key and URI. For example, when a gadget is created that is a part of an application that isn't installed.

=item C<< moduleKey >>

The module key of the gadget type. Can't be provided with C<uri>.

=item C<< position >>

The position of the gadget. When the gadget is placed into the position, other gadgets in the same column are moved down to accommodate it.

=item C<< title >>

The title of the gadget.

=item C<< uri >>

The URI of the gadget type. Can't be provided with C<moduleKey>.

=back

Returns a L<< JIRA::API::DashboardGadget >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_addGadget_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/gadget' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DashboardGadgetSettings->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addGadget( $self, %options ) {
    my $tx = $self->_build_addGadget_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::DashboardGadget->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeGadget >>

  my $res = $client->removeGadget()->get;

Remove gadget from dashboard

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< gadgetId >>

The ID of the gadget.

=back


Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_removeGadget_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };
    croak "Missing required parameter 'gadgetId'"
        unless exists $options{ 'gadgetId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/gadget/{gadgetId}' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
              'gadgetId' => delete $options{'gadgetId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub removeGadget( $self, %options ) {
    my $tx = $self->_build_removeGadget_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the gadget or the dashboard is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateGadget >>

  my $res = $client->updateGadget()->get;

Update gadget on dashboard

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< gadgetId >>

The ID of the gadget.

=back


=head3 Options

=over 4

=item C<< color >>

The color of the gadget. Should be one of C<blue>, C<red>, C<yellow>, C<green>, C<cyan>, C<purple>, C<gray>, or C<white>.

=item C<< position >>

The position of the gadget.

=item C<< title >>

The title of the gadget.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_updateGadget_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };
    croak "Missing required parameter 'gadgetId'"
        unless exists $options{ 'gadgetId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/gadget/{gadgetId}' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
              'gadgetId' => delete $options{'gadgetId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DashboardGadgetUpdateRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateGadget( $self, %options ) {
    my $tx = $self->_build_updateGadget_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the gadget or the dashboard is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDashboardItemPropertyKeys >>

  my $res = $client->getDashboardItemPropertyKeys()->get;

Get dashboard item property keys

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< itemId >>

The ID of the dashboard item.

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getDashboardItemPropertyKeys_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };
    croak "Missing required parameter 'itemId'"
        unless exists $options{ 'itemId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/items/{itemId}/properties' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
              'itemId' => delete $options{'itemId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDashboardItemPropertyKeys( $self, %options ) {
    my $tx = $self->_build_getDashboardItemPropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard or dashboard item is not found, or the dashboard is not owned by or shared with the user.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteDashboardItemProperty >>

  my $res = $client->deleteDashboardItemProperty()->get;

Delete dashboard item property

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< itemId >>

The ID of the dashboard item.

=item B<< propertyKey >>

The key of the dashboard item property.

=back



=cut

sub _build_deleteDashboardItemProperty_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };
    croak "Missing required parameter 'itemId'"
        unless exists $options{ 'itemId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/items/{itemId}/properties/{propertyKey}' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
              'itemId' => delete $options{'itemId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteDashboardItemProperty( $self, %options ) {
    my $tx = $self->_build_deleteDashboardItemProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the dashboard item property is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the dashboard or dashboard item ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not the owner of the dashboard.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard item is not found or the dashboard is not shared with the user.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDashboardItemProperty >>

  my $res = $client->getDashboardItemProperty()->get;

Get dashboard item property

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< itemId >>

The ID of the dashboard item.

=item B<< propertyKey >>

The key of the dashboard item property.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getDashboardItemProperty_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };
    croak "Missing required parameter 'itemId'"
        unless exists $options{ 'itemId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/items/{itemId}/properties/{propertyKey}' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
              'itemId' => delete $options{'itemId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDashboardItemProperty( $self, %options ) {
    my $tx = $self->_build_getDashboardItemProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard, the dashboard item, or dashboard item property is not found, or the dashboard is not owned by or shared with the user.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setDashboardItemProperty >>

  my $res = $client->setDashboardItemProperty()->get;

Set dashboard item property

=head3 Parameters

=over 4

=item B<< dashboardId >>

The ID of the dashboard.

=item B<< itemId >>

The ID of the dashboard item.

=item B<< propertyKey >>

The key of the dashboard item property. The maximum length is 255 characters. For dashboard items with a spec URI and no complete module key, if the provided propertyKey is equal to "config", the request body's JSON must be an object with all keys and values as strings.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setDashboardItemProperty_request( $self, %options ) {
    croak "Missing required parameter 'dashboardId'"
        unless exists $options{ 'dashboardId' };
    croak "Missing required parameter 'itemId'"
        unless exists $options{ 'itemId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{dashboardId}/items/{itemId}/properties/{propertyKey}' );
    my $path = $template->process(
              'dashboardId' => delete $options{'dashboardId'},
              'itemId' => delete $options{'itemId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setDashboardItemProperty( $self, %options ) {
    my $tx = $self->_build_setDashboardItemProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the dashboard item property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the dashboard item property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * Request is invalid * Or if all of these conditions are met in the request: * The dashboard item has a spec URI and no complete module key * The value of propertyKey is equal to "config" * The request body contains a JSON object whose keys and values are not strings.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user is not the owner of the dashboard.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard item is not found or the dashboard is not shared with the user.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteDashboard >>

  my $res = $client->deleteDashboard()->get;

Delete dashboard

=head3 Parameters

=over 4

=item B<< id >>

The ID of the dashboard.

=back


Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deleteDashboard_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteDashboard( $self, %options ) {
    my $tx = $self->_build_deleteDashboard_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the dashboard is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # 400 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDashboard >>

  my $res = $client->getDashboard()->get;

Get dashboard

=head3 Parameters

=over 4

=item B<< id >>

The ID of the dashboard.

=back


Returns a L<< JIRA::API::Dashboard >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getDashboard_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDashboard( $self, %options ) {
    my $tx = $self->_build_getDashboard_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Dashboard->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # 400 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard is not found or the dashboard is not owned by or shared with the user.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateDashboard >>

  my $res = $client->updateDashboard()->get;

Update dashboard

=head3 Parameters

=over 4

=item B<< id >>

The ID of the dashboard to update.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the dashboard.

=item C<< editPermissions >>

The edit permissions for the dashboard.

=item C<< name >>

The name of the dashboard.

=item C<< sharePermissions >>

The share permissions for the dashboard.

=back

Returns a L<< JIRA::API::Dashboard >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_updateDashboard_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DashboardDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateDashboard( $self, %options ) {
    my $tx = $self->_build_updateDashboard_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Dashboard->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard is not found or the dashboard is not owned by the user.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< copyDashboard >>

  my $res = $client->copyDashboard()->get;

Copy dashboard

=head3 Parameters

=over 4

=item B<< id >>

=back


=head3 Options

=over 4

=item C<< description >>

The description of the dashboard.

=item C<< editPermissions >>

The edit permissions for the dashboard.

=item C<< name >>

The name of the dashboard.

=item C<< sharePermissions >>

The share permissions for the dashboard.

=back

Returns a L<< JIRA::API::Dashboard >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_copyDashboard_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/dashboard/{id}/copy' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DashboardDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub copyDashboard( $self, %options ) {
    my $tx = $self->_build_copyDashboard_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Dashboard->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the dashboard is not found or the dashboard is not owned by or shared with the user.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getEvents >>

  my $res = $client->getEvents()->get;

Get events

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::IssueEvent >>.

=cut

sub _build_getEvents_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/events';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getEvents( $self, %options ) {
    my $tx = $self->_build_getEvents_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::IssueEvent->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to complete this request.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< analyseExpression >>

  my $res = $client->analyseExpression()->get;

Analyse Jira expression

=head3 Parameters

=over 4

=item B<< check >>

The check to perform:

=over

=item *

C<syntax> Each expression's syntax is checked to ensure the expression can be parsed. Also, syntactic limits are validated. For example, the expression's length.


=item *

C<type> EXPERIMENTAL. Each expression is type checked and the final type of the expression inferred. Any type errors that would result in the expression failure at runtime are reported. For example, accessing properties that don't exist or passing the wrong number of arguments to functions. Also performs the syntax check.


=item *

C<complexity> EXPERIMENTAL. Determines the formulae for how many L<expensive operations|https://developer.atlassian.com/cloud/jira/platform/jira-expressions/#expensive-operations> each expression may execute.


=back

=back


=head3 Options

=over 4

=item C<< contextVariables >>

Context variables and their types. The type checker assumes that L<common context variables|https://developer.atlassian.com/cloud/jira/platform/jira-expressions/#context-variables>, such as C<issue> or C<project>, are available in context and sets their type. Use this property to override the default types or provide details of new variables.

=item C<< expressions >>

The list of Jira expressions to analyse.

=back

Returns a L<< JIRA::API::JiraExpressionsAnalysis >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_analyseExpression_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/expression/analyse';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'check' => delete $options{'check'},
    );

    my $request = JIRA::API::JiraExpressionForAnalysis->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub analyseExpression( $self, %options ) {
    my $tx = $self->_build_analyseExpression_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::JiraExpressionsAnalysis->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # 400 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # 404 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< evaluateJiraExpression >>

  my $res = $client->evaluateJiraExpression()->get;

Evaluate Jira expression

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts C<meta.complexity> that returns information about the expression complexity. For example, the number of expensive operations used by the expression and how close the expression is to reaching the L<complexity limit|https://developer.atlassian.com/cloud/jira/platform/jira-expressions/#restrictions>. Useful when designing and debugging your expressions.

=back


=head3 Options

=over 4

=item C<< context >>

The context in which the Jira expression is evaluated.

=item C<< expression >>

The Jira expression to evaluate.

=back

Returns a L<< JIRA::API::JiraExpressionResult >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_evaluateJiraExpression_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/expression/eval';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::JiraExpressionEvalRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub evaluateJiraExpression( $self, %options ) {
    my $tx = $self->_build_evaluateJiraExpression_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the evaluation results in a value. The result is a JSON primitive value, list, or object.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::JiraExpressionResult->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the request is invalid, that is: * invalid data is provided, such as a request including issue ID and key. * the expression is invalid and can not be parsed. * evaluation fails at runtime. This may happen for various reasons. For example, accessing a property on a null object (such as the expression `issue.id` where `issue` is `null`). In this case an error message is provided.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any object provided in the request context is not found or the user does not have permission to view it.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFields >>

  my $res = $client->getFields()->get;

Get fields

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::FieldDetails >>.

=cut

sub _build_getFields_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/field';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFields( $self, %options ) {
    my $tx = $self->_build_getFields_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::FieldDetails->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createCustomField >>

  my $res = $client->createCustomField()->get;

Create custom field

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the custom field, which is displayed in Jira.

=item C<< name >>

The name of the custom field, which is displayed in Jira. This is not the unique identifier.

=item C<< searcherKey >>

The searcher defines the way the field is searched in Jira. For example, I<com.atlassian.jira.plugin.system.customfieldtypes:grouppickersearcher>.

The search UI (basic search and JQL search) will display different operations and values for the field, based on the field searcher. You must specify a searcher that is valid for the field type, as listed below (abbreviated values shown):

=over

=item *

C<cascadingselect>: C<cascadingselectsearcher>


=item *

C<datepicker>: C<daterange>


=item *

C<datetime>: C<datetimerange>


=item *

C<float>: C<exactnumber> or C<numberrange>


=item *

C<grouppicker>: C<grouppickersearcher>


=item *

C<importid>: C<exactnumber> or C<numberrange>


=item *

C<labels>: C<labelsearcher>


=item *

C<multicheckboxes>: C<multiselectsearcher>


=item *

C<multigrouppicker>: C<multiselectsearcher>


=item *

C<multiselect>: C<multiselectsearcher>


=item *

C<multiuserpicker>: C<userpickergroupsearcher>


=item *

C<multiversion>: C<versionsearcher>


=item *

C<project>: C<projectsearcher>


=item *

C<radiobuttons>: C<multiselectsearcher>


=item *

C<readonlyfield>: C<textsearcher>


=item *

C<select>: C<multiselectsearcher>


=item *

C<textarea>: C<textsearcher>


=item *

C<textfield>: C<textsearcher>


=item *

C<url>: C<exacttextsearcher>


=item *

C<userpicker>: C<userpickergroupsearcher>


=item *

C<version>: C<versionsearcher>


=back

If no searcher is provided, the field isn't searchable. However, L<Forge custom fields|https://developer.atlassian.com/platform/forge/manifest-reference/modules/#jira-custom-field-type--beta-> have a searcher set automatically, so are always searchable.

=item C<< type >>

The type of the custom field. These built-in custom field types are available:

=over

=item *

C<cascadingselect>: Enables values to be selected from two levels of select lists (value: C<com.atlassian.jira.plugin.system.customfieldtypes:cascadingselect>)


=item *

C<datepicker>: Stores a date using a picker control (value: C<com.atlassian.jira.plugin.system.customfieldtypes:datepicker>)


=item *

C<datetime>: Stores a date with a time component (value: C<com.atlassian.jira.plugin.system.customfieldtypes:datetime>)


=item *

C<float>: Stores and validates a numeric (floating point) input (value: C<com.atlassian.jira.plugin.system.customfieldtypes:float>)


=item *

C<grouppicker>: Stores a user group using a picker control (value: C<com.atlassian.jira.plugin.system.customfieldtypes:grouppicker>)


=item *

C<importid>: A read-only field that stores the ID the issue had in the system it was imported from (value: C<com.atlassian.jira.plugin.system.customfieldtypes:importid>)


=item *

C<labels>: Stores labels (value: C<com.atlassian.jira.plugin.system.customfieldtypes:labels>)


=item *

C<multicheckboxes>: Stores multiple values using checkboxes (value: ``)


=item *

C<multigrouppicker>: Stores multiple user groups using a picker control (value: ``)


=item *

C<multiselect>: Stores multiple values using a select list (value: C<com.atlassian.jira.plugin.system.customfieldtypes:multicheckboxes>)


=item *

C<multiuserpicker>: Stores multiple users using a picker control (value: C<com.atlassian.jira.plugin.system.customfieldtypes:multigrouppicker>)


=item *

C<multiversion>: Stores multiple versions from the versions available in a project using a picker control (value: C<com.atlassian.jira.plugin.system.customfieldtypes:multiversion>)


=item *

C<project>: Stores a project from a list of projects that the user is permitted to view (value: C<com.atlassian.jira.plugin.system.customfieldtypes:project>)


=item *

C<radiobuttons>: Stores a value using radio buttons (value: C<com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons>)


=item *

C<readonlyfield>: Stores a read-only text value, which can only be populated via the API (value: C<com.atlassian.jira.plugin.system.customfieldtypes:readonlyfield>)


=item *

C<select>: Stores a value from a configurable list of options (value: C<com.atlassian.jira.plugin.system.customfieldtypes:select>)


=item *

C<textarea>: Stores a long text string using a multiline text area (value: C<com.atlassian.jira.plugin.system.customfieldtypes:textarea>)


=item *

C<textfield>: Stores a text string using a single-line text box (value: C<com.atlassian.jira.plugin.system.customfieldtypes:textfield>)


=item *

C<url>: Stores a URL (value: C<com.atlassian.jira.plugin.system.customfieldtypes:url>)


=item *

C<userpicker>: Stores a user using a picker control (value: C<com.atlassian.jira.plugin.system.customfieldtypes:userpicker>)


=item *

C<version>: Stores a version using a picker control (value: C<com.atlassian.jira.plugin.system.customfieldtypes:version>)


=back

To create a field based on a L<Forge custom field type|https://developer.atlassian.com/platform/forge/manifest-reference/modules/#jira-custom-field-type--beta->, use the ID of the Forge custom field type as the value. For example, C<ari:cloud:ecosystem::extension/e62f20a2-4b61-4dbe-bfb9-9a88b5e3ac84/548c5df1-24aa-4f7c-bbbb-3038d947cb05/static/my-cf-type-key>.

=back

Returns a L<< JIRA::API::FieldDetails >>.

=cut

sub _build_createCustomField_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/field';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CustomFieldDefinitionJsonBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createCustomField( $self, %options ) {
    my $tx = $self->_build_createCustomField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the custom field is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FieldDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the user does not have permission to create custom fields. * any of the request object properties have invalid or missing values.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFieldsPaginated >>

  my $res = $client->getFieldsPaginated()->get;

Get fields paginated

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< type >>

The type of fields to search.

=item B<< id >>

The IDs of the custom fields to return or, where C<query> is specified, filter.

=item B<< query >>

String used to perform a case-insensitive partial match with field names or descriptions.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<contextsCount> sorts by the number of contexts related to a field


=item *

C<lastUsed> sorts by the date when the value of the field last changed


=item *

C<name> sorts by the field name


=item *

C<screensCount> sorts by the number of screens related to a field


=back

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<key> returns the key for each field


=item *

C<lastUsed> returns the date when the value of the field last changed


=item *

C<screensCount> returns the number of screens related to a field


=item *

C<contextsCount> returns the number of contexts related to a field


=item *

C<isLocked> returns information about whether the field is L<locked|https://confluence.atlassian.com/x/ZSN7Og>


=item *

C<searcherKey> returns the searcher key for each custom field


=back

=back


Returns a L<< JIRA::API::PageBeanField >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getFieldsPaginated_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/field/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'type' => delete $options{'type'},
        maybe 'id' => delete $options{'id'},
        maybe 'query' => delete $options{'query'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFieldsPaginated( $self, %options ) {
    my $tx = $self->_build_getFieldsPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanField->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getTrashedFieldsPaginated >>

  my $res = $client->getTrashedFieldsPaginated()->get;

Get fields in trash paginated

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

=item B<< query >>

String used to perform a case-insensitive partial match with field names or descriptions.

=item B<< expand >>

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<name> sorts by the field name


=item *

C<trashDate> sorts by the date the field was moved to the trash


=item *

C<plannedDeletionDate> sorts by the planned deletion date


=back

=back


Returns a L<< JIRA::API::PageBeanField >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getTrashedFieldsPaginated_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/field/search/trashed';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'query' => delete $options{'query'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'orderBy' => delete $options{'orderBy'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getTrashedFieldsPaginated( $self, %options ) {
    my $tx = $self->_build_getTrashedFieldsPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanField->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateCustomField >>

  my $res = $client->updateCustomField()->get;

Update custom field

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the custom field. The maximum length is 40000 characters.

=item C<< name >>

The name of the custom field. It doesn't have to be unique. The maximum length is 255 characters.

=item C<< searcherKey >>

The searcher that defines the way the field is searched in Jira. It can be set to C<null>, otherwise you must specify the valid searcher for the field type, as listed below (abbreviated values shown):

=over

=item *

C<cascadingselect>: C<cascadingselectsearcher>


=item *

C<datepicker>: C<daterange>


=item *

C<datetime>: C<datetimerange>


=item *

C<float>: C<exactnumber> or C<numberrange>


=item *

C<grouppicker>: C<grouppickersearcher>


=item *

C<importid>: C<exactnumber> or C<numberrange>


=item *

C<labels>: C<labelsearcher>


=item *

C<multicheckboxes>: C<multiselectsearcher>


=item *

C<multigrouppicker>: C<multiselectsearcher>


=item *

C<multiselect>: C<multiselectsearcher>


=item *

C<multiuserpicker>: C<userpickergroupsearcher>


=item *

C<multiversion>: C<versionsearcher>


=item *

C<project>: C<projectsearcher>


=item *

C<radiobuttons>: C<multiselectsearcher>


=item *

C<readonlyfield>: C<textsearcher>


=item *

C<select>: C<multiselectsearcher>


=item *

C<textarea>: C<textsearcher>


=item *

C<textfield>: C<textsearcher>


=item *

C<url>: C<exacttextsearcher>


=item *

C<userpicker>: C<userpickergroupsearcher>


=item *

C<version>: C<versionsearcher>


=back

=back

Returns a L<<  >>.

=cut

sub _build_updateCustomField_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateCustomFieldDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateCustomField( $self, %options ) {
    my $tx = $self->_build_updateCustomField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getContextsForField >>

  my $res = $client->getContextsForField()->get;

Get custom field contexts

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< isAnyIssueType >>

Whether to return contexts that apply to all issue types.

=item B<< isGlobalContext >>

Whether to return contexts that apply to all projects.

=item B<< contextId >>

The list of context IDs. To include multiple contexts, separate IDs with ampersand: C<contextId=10000&contextId=10001>.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanCustomFieldContext >>.

=cut

sub _build_getContextsForField_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'isAnyIssueType' => delete $options{'isAnyIssueType'},
        maybe 'isGlobalContext' => delete $options{'isGlobalContext'},
        maybe 'contextId' => delete $options{'contextId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getContextsForField( $self, %options ) {
    my $tx = $self->_build_getContextsForField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanCustomFieldContext->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field was not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createCustomFieldContext >>

  my $res = $client->createCustomFieldContext()->get;

Create custom field context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the context.

=item C<< id >>

The ID of the context.

=item C<< issueTypeIds >>

The list of issue types IDs for the context. If the list is empty, the context refers to all issue types.

=item C<< name >>

The name of the context.

=item C<< projectIds >>

The list of project IDs associated with the context. If the list is empty, the context is global.

=back

Returns a L<< JIRA::API::CreateCustomFieldContext >>.

=cut

sub _build_createCustomFieldContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateCustomFieldContext->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createCustomFieldContext( $self, %options ) {
    my $tx = $self->_build_createCustomFieldContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the custom field context is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CreateCustomFieldContext->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field, project, or issue type is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type is a sub-task, but sub-tasks are disabled in Jira settings.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDefaultValues >>

  my $res = $client->getDefaultValues()->get;

Get custom field contexts default values

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field, for example C<customfield\_10000>.

=item B<< contextId >>

The IDs of the contexts.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanCustomFieldContextDefaultValue >>.

=cut

sub _build_getDefaultValues_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/defaultValue' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'contextId' => delete $options{'contextId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDefaultValues( $self, %options ) {
    my $tx = $self->_build_getDefaultValues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanCustomFieldContextDefaultValue->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setDefaultValues >>

  my $res = $client->setDefaultValues()->get;

Set custom field contexts default values

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=back


=head3 Options

=over 4

=item C<< defaultValues >>

=back

Returns a L<<  >>.

=cut

sub _build_setDefaultValues_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/defaultValue' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CustomFieldContextDefaultValueUpdate->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setDefaultValues( $self, %options ) {
    my $tx = $self->_build_setDefaultValues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if operation is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field, a context, an option, or a cascading option is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeMappingsForContexts >>

  my $res = $client->getIssueTypeMappingsForContexts()->get;

Get issue types for custom field context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context. To include multiple contexts, provide an ampersand-separated list. For example, C<contextId=10001&contextId=10002>.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeToContextMapping >>.

=cut

sub _build_getIssueTypeMappingsForContexts_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/issuetypemapping' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'contextId' => delete $options{'contextId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeMappingsForContexts( $self, %options ) {
    my $tx = $self->_build_getIssueTypeMappingsForContexts_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if operation is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeToContextMapping->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCustomFieldContextsForProjectsAndIssueTypes >>

  my $res = $client->getCustomFieldContextsForProjectsAndIssueTypes()->get;

Get custom field contexts for projects and issue types

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


=head3 Options

=over 4

=item C<< mappings >>

The project and issue type mappings.

=back

Returns a L<< JIRA::API::PageBeanContextForProjectAndIssueType >>.

=cut

sub _build_getCustomFieldContextsForProjectsAndIssueTypes_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/mapping' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $request = JIRA::API::ProjectIssueTypeMappings->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getCustomFieldContextsForProjectsAndIssueTypes( $self, %options ) {
    my $tx = $self->_build_getCustomFieldContextsForProjectsAndIssueTypes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanContextForProjectAndIssueType->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field, project, or issue type is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectContextMapping >>

  my $res = $client->getProjectContextMapping()->get;

Get project mappings for custom field context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field, for example C<customfield\_10000>.

=item B<< contextId >>

The list of context IDs. To include multiple context, separate IDs with ampersand: C<contextId=10000&contextId=10001>.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanCustomFieldContextProjectMapping >>.

=cut

sub _build_getProjectContextMapping_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/projectmapping' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'contextId' => delete $options{'contextId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectContextMapping( $self, %options ) {
    my $tx = $self->_build_getProjectContextMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanCustomFieldContextProjectMapping->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteCustomFieldContext >>

  my $res = $client->deleteCustomFieldContext()->get;

Delete custom field context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


Returns a L<<  >>.

=cut

sub _build_deleteCustomFieldContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteCustomFieldContext( $self, %options ) {
    my $tx = $self->_build_deleteCustomFieldContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the context is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field or the context is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateCustomFieldContext >>

  my $res = $client->updateCustomFieldContext()->get;

Update custom field context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the custom field context. The maximum length is 255 characters.

=item C<< name >>

The name of the custom field context. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<<  >>.

=cut

sub _build_updateCustomFieldContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CustomFieldContextUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateCustomFieldContext( $self, %options ) {
    my $tx = $self->_build_updateCustomFieldContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the context is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field or the context is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addIssueTypesToContext >>

  my $res = $client->addIssueTypesToContext()->get;

Add issue types to context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< issueTypeIds >>

The list of issue type IDs.

=back

Returns a L<<  >>.

=cut

sub _build_addIssueTypesToContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/issuetype' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addIssueTypesToContext( $self, %options ) {
    my $tx = $self->_build_addIssueTypesToContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if operation is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field, context, or one or more issue types are not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type is a sub-task, but sub-tasks are disabled in Jira settings.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeIssueTypesFromContext >>

  my $res = $client->removeIssueTypesFromContext()->get;

Remove issue types from context

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< issueTypeIds >>

The list of issue type IDs.

=back

Returns a L<<  >>.

=cut

sub _build_removeIssueTypesFromContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/issuetype/remove' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub removeIssueTypesFromContext( $self, %options ) {
    my $tx = $self->_build_removeIssueTypesFromContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if operation is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field, context, or one or more issue types are not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getOptionsForContext >>

  my $res = $client->getOptionsForContext()->get;

Get custom field options (context)

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=item B<< optionId >>

The ID of the option.

=item B<< onlyOptions >>

Whether only options are returned.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanCustomFieldContextOption >>.

=cut

sub _build_getOptionsForContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/option' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'optionId' => delete $options{'optionId'},
        maybe 'onlyOptions' => delete $options{'onlyOptions'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getOptionsForContext( $self, %options ) {
    my $tx = $self->_build_getOptionsForContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanCustomFieldContextOption->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found or the context doesn't match the custom field.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createCustomFieldOption >>

  my $res = $client->createCustomFieldOption()->get;

Create custom field options (context)

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< options >>

Details of options to create.

=back

Returns a L<< JIRA::API::CustomFieldCreatedContextOptionsList >>.

=cut

sub _build_createCustomFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/option' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::BulkCustomFieldOptionCreateRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createCustomFieldOption( $self, %options ) {
    my $tx = $self->_build_createCustomFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CustomFieldCreatedContextOptionsList->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found or the context doesn't match the custom field.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateCustomFieldOption >>

  my $res = $client->updateCustomFieldOption()->get;

Update custom field options (context)

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< options >>

Details of the options to update.

=back

Returns a L<< JIRA::API::CustomFieldUpdatedContextOptionsList >>.

=cut

sub _build_updateCustomFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/option' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::BulkCustomFieldOptionUpdateRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateCustomFieldOption( $self, %options ) {
    my $tx = $self->_build_updateCustomFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CustomFieldUpdatedContextOptionsList->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the field, context, or one or more options is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< reorderCustomFieldOptions >>

  my $res = $client->reorderCustomFieldOptions()->get;

Reorder custom field options (context)

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< after >>

The ID of the custom field option or cascading option to place the moved options after. Required if C<position> isn't provided.

=item C<< customFieldOptionIds >>

A list of IDs of custom field options to move. The order of the custom field option IDs in the list is the order they are given after the move. The list must contain custom field options or cascading options, but not both.

=item C<< position >>

The position the custom field options should be moved to. Required if C<after> isn't provided.

=back

Returns a L<<  >>.

=cut

sub _build_reorderCustomFieldOptions_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/option/move' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::OrderOfCustomFieldOptions->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub reorderCustomFieldOptions( $self, %options ) {
    my $tx = $self->_build_reorderCustomFieldOptions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if options are reordered.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the field, the context, or one or more of the options is not found..
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteCustomFieldOption >>

  my $res = $client->deleteCustomFieldOption()->get;

Delete custom field options (context)

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context from which an option should be deleted.

=item B<< optionId >>

The ID of the option to delete.

=back



=cut

sub _build_deleteCustomFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };
    croak "Missing required parameter 'optionId'"
        unless exists $options{ 'optionId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/option/{optionId}' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
              'optionId' => delete $options{'optionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteCustomFieldOption( $self, %options ) {
    my $tx = $self->_build_deleteCustomFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the option is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the field, the context, or the option is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignProjectsToCustomFieldContext >>

  my $res = $client->assignProjectsToCustomFieldContext()->get;

Assign custom field context to projects

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< projectIds >>

The IDs of projects.

=back

Returns a L<<  >>.

=cut

sub _build_assignProjectsToCustomFieldContext_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/project' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignProjectsToCustomFieldContext( $self, %options ) {
    my $tx = $self->_build_assignProjectsToCustomFieldContext_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if operation is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field, context, or project is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeCustomFieldContextFromProjects >>

  my $res = $client->removeCustomFieldContextFromProjects()->get;

Remove custom field context from projects

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the custom field.

=item B<< contextId >>

The ID of the context.

=back


=head3 Options

=over 4

=item C<< projectIds >>

The IDs of projects.

=back

Returns a L<<  >>.

=cut

sub _build_removeCustomFieldContextFromProjects_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };
    croak "Missing required parameter 'contextId'"
        unless exists $options{ 'contextId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/context/{contextId}/project/remove' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
              'contextId' => delete $options{'contextId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub removeCustomFieldContextFromProjects( $self, %options ) {
    my $tx = $self->_build_removeCustomFieldContextFromProjects_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the custom field context is removed from the projects.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field, context, or one or more projects are not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getContextsForFieldDeprecated >>

  my $res = $client->getContextsForFieldDeprecated()->get;

Get contexts for a field

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the field to return contexts for.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanContext >>.

=cut

sub _build_getContextsForFieldDeprecated_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/contexts' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getContextsForFieldDeprecated( $self, %options ) {
    my $tx = $self->_build_getContextsForFieldDeprecated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanContext->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getScreensForField >>

  my $res = $client->getScreensForField()->get;

Get screens for a field

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the field to return screens for.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about screens in the response. This parameter accepts C<tab> which returns details about the screen tabs the field is used in.

=back


Returns a L<< JIRA::API::PageBeanScreenWithTab >>.

=cut

sub _build_getScreensForField_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldId}/screens' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getScreensForField( $self, %options ) {
    my $tx = $self->_build_getScreensForField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanScreenWithTab->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllIssueFieldOptions >>

  my $res = $client->getAllIssueFieldOptions()->get;

Get all issue field options

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=back


Returns a L<< JIRA::API::PageBeanIssueFieldOption >>.

=cut

sub _build_getAllIssueFieldOptions_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllIssueFieldOptions( $self, %options ) {
    my $tx = $self->_build_getAllIssueFieldOptions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the field is not found or does not support options.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as a Jira administrator or the app that provided the field.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssueFieldOption >>

  my $res = $client->createIssueFieldOption()->get;

Create issue field option

=head3 Parameters

=over 4

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=back


=head3 Options

=over 4

=item C<< config >>

Details of the projects the option is available in.

=item C<< properties >>

The properties of the option as arbitrary key-value pairs. These properties can be searched using JQL, if the extractions (see https://developer.atlassian.com/cloud/jira/platform/modules/issue-field-option-property-index/) are defined in the descriptor for the issue field module.

=item C<< value >>

The option's name, which is displayed in Jira.

=back

Returns a L<< JIRA::API::IssueFieldOption >>.

=cut

sub _build_createIssueFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueFieldOptionCreateBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssueFieldOption( $self, %options ) {
    my $tx = $self->_build_createIssueFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the option is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as a Jira administrator or the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field is not found or does not support options.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getSelectableIssueFieldOptions >>

  my $res = $client->getSelectableIssueFieldOptions()->get;

Get selectable issue field options

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< projectId >>

Filters the results to options that are only available in the specified project.

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=back


Returns a L<< JIRA::API::PageBeanIssueFieldOption >>.

=cut

sub _build_getSelectableIssueFieldOptions_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option/suggestions/edit' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getSelectableIssueFieldOptions( $self, %options ) {
    my $tx = $self->_build_getSelectableIssueFieldOptions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field is not found or does not support options.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getVisibleIssueFieldOptions >>

  my $res = $client->getVisibleIssueFieldOptions()->get;

Get visible issue field options

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< projectId >>

Filters the results to options that are only available in the specified project.

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=back


Returns a L<< JIRA::API::PageBeanIssueFieldOption >>.

=cut

sub _build_getVisibleIssueFieldOptions_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option/suggestions/search' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getVisibleIssueFieldOptions( $self, %options ) {
    my $tx = $self->_build_getVisibleIssueFieldOptions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field is not found or does not support options.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueFieldOption >>

  my $res = $client->deleteIssueFieldOption()->get;

Delete issue field option

=head3 Parameters

=over 4

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=item B<< optionId >>

The ID of the option to be deleted.

=back


Returns a L<<  >>.

=cut

sub _build_deleteIssueFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };
    croak "Missing required parameter 'optionId'"
        unless exists $options{ 'optionId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option/{optionId}' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
              'optionId' => delete $options{'optionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteIssueFieldOption( $self, %options ) {
    my $tx = $self->_build_deleteIssueFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the field option is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as a Jira administrator or the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field or option is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the option is selected for the field in any issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueFieldOption >>

  my $res = $client->getIssueFieldOption()->get;

Get issue field option

=head3 Parameters

=over 4

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=item B<< optionId >>

The ID of the option to be returned.

=back


Returns a L<< JIRA::API::IssueFieldOption >>.

=cut

sub _build_getIssueFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };
    croak "Missing required parameter 'optionId'"
        unless exists $options{ 'optionId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option/{optionId}' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
              'optionId' => delete $options{'optionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueFieldOption( $self, %options ) {
    my $tx = $self->_build_getIssueFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the requested option is returned.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the field is not found or does not support options.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as a Jira administrator or the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the option is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateIssueFieldOption >>

  my $res = $client->updateIssueFieldOption()->get;

Update issue field option

=head3 Parameters

=over 4

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=item B<< optionId >>

The ID of the option to be updated.

=back


=head3 Options

=over 4

=item C<< config >>

Details of the projects the option is available in.

=item C<< id >>

The unique identifier for the option. This is only unique within the select field's set of options.

=item C<< properties >>

The properties of the object, as arbitrary key-value pairs. These properties can be searched using JQL, if the extractions (see L<Issue Field Option Property Index|https://developer.atlassian.com/cloud/jira/platform/modules/issue-field-option-property-index/>) are defined in the descriptor for the issue field module.

=item C<< value >>

The option's name, which is displayed in Jira.

=back

Returns a L<< JIRA::API::IssueFieldOption >>.

=cut

sub _build_updateIssueFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };
    croak "Missing required parameter 'optionId'"
        unless exists $options{ 'optionId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option/{optionId}' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
              'optionId' => delete $options{'optionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueFieldOption->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateIssueFieldOption( $self, %options ) {
    my $tx = $self->_build_updateIssueFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the option is updated or created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueFieldOption->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the option is invalid, or the *ID* in the request object does not match the *optionId* parameter.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not authenticated as a Jira administrator or the app that provided the field.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< replaceIssueFieldOption >>

  my $res = $client->replaceIssueFieldOption()->get;

Replace issue field option

=head3 Parameters

=over 4

=item B<< replaceWith >>

The ID of the option that will replace the currently selected option.

=item B<< jql >>

A JQL query that specifies the issues to be updated. For example, I<project=10000>.

=item B<< overrideScreenSecurity >>

Whether screen security is overridden to enable hidden fields to be edited. Available to Connect and Forge app users with admin permission.

=item B<< overrideEditableFlag >>

Whether screen security is overridden to enable uneditable fields to be edited. Available to Connect and Forge app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=item B<< fieldKey >>

The field key is specified in the following format: B<$(app-key)__$(field-key)>. For example, I<example-add-on__example-issue-field>. To determine the C<fieldKey> value, do one of the following:

=over

=item *

open the app's plugin descriptor, then B<app-key> is the key at the top and B<field-key> is the key in the C<jiraIssueFields> module. B<app-key> can also be found in the app listing in the Atlassian Universal Plugin Manager.


=item *

run L<Get fields|#api-rest-api-3-field-get> and in the field details the value is returned in C<key>. For example, C<"key": "teams-add-on__team-issue-field">


=back

=item B<< optionId >>

The ID of the option to be deselected.

=back


Returns a L<< JIRA::API::TaskProgressBeanRemoveOptionFromIssuesResult >>.

=cut

sub _build_replaceIssueFieldOption_request( $self, %options ) {
    croak "Missing required parameter 'fieldKey'"
        unless exists $options{ 'fieldKey' };
    croak "Missing required parameter 'optionId'"
        unless exists $options{ 'optionId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/field/{fieldKey}/option/{optionId}/issue' );
    my $path = $template->process(
              'fieldKey' => delete $options{'fieldKey'},
              'optionId' => delete $options{'optionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'replaceWith' => delete $options{'replaceWith'},
        maybe 'jql' => delete $options{'jql'},
        maybe 'overrideScreenSecurity' => delete $options{'overrideScreenSecurity'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub replaceIssueFieldOption( $self, %options ) {
    my $tx = $self->_build_replaceIssueFieldOption_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the long-running task to deselect the option is started.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanRemoveOptionFromIssuesResult->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the field is not found or does not support options, or the options to be replaced are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteCustomField >>

  my $res = $client->deleteCustomField()->get;

Delete custom field

=head3 Parameters

=over 4

=item B<< id >>

The ID of a custom field.

=back


Returns a L<< JIRA::API::TaskProgressBeanObject >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deleteCustomField_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/field/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteCustomField( $self, %options ) {
    my $tx = $self->_build_deleteCustomField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanObject->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if any of these are true: * The custom field is locked. * The custom field is used in a issue security scheme or a permission scheme. * The custom field ID format is incorrect.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if a task to delete the custom field is running.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< restoreCustomField >>

  my $res = $client->restoreCustomField()->get;

Restore custom field from trash

=head3 Parameters

=over 4

=item B<< id >>

The ID of a custom field.

=back


Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_restoreCustomField_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{id}/restore' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub restoreCustomField( $self, %options ) {
    my $tx = $self->_build_restoreCustomField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< trashCustomField >>

  my $res = $client->trashCustomField()->get;

Move custom field to trash

=head3 Parameters

=over 4

=item B<< id >>

The ID of a custom field.

=back


Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_trashCustomField_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/field/{id}/trash' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub trashCustomField( $self, %options ) {
    my $tx = $self->_build_trashCustomField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the custom field is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllFieldConfigurations >>

  my $res = $client->getAllFieldConfigurations()->get;

Get all field configurations

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of field configuration IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>.

=item B<< isDefault >>

If I<true> returns default field configurations only.

=item B<< query >>

The query string used to match against field configuration names and descriptions.

=back


Returns a L<< JIRA::API::PageBeanFieldConfigurationDetails >>.

=cut

sub _build_getAllFieldConfigurations_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/fieldconfiguration';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'isDefault' => delete $options{'isDefault'},
        maybe 'query' => delete $options{'query'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllFieldConfigurations( $self, %options ) {
    my $tx = $self->_build_getAllFieldConfigurations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanFieldConfigurationDetails->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createFieldConfiguration >>

  my $res = $client->createFieldConfiguration()->get;

Create field configuration

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the field configuration.

=item C<< name >>

The name of the field configuration. Must be unique.

=back

Returns a L<< JIRA::API::FieldConfiguration >>.

=cut

sub _build_createFieldConfiguration_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/fieldconfiguration';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::FieldConfigurationDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createFieldConfiguration( $self, %options ) {
    my $tx = $self->_build_createFieldConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FieldConfiguration->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteFieldConfiguration >>

  my $res = $client->deleteFieldConfiguration()->get;

Delete field configuration

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration.

=back


Returns a L<<  >>.

=cut

sub _build_deleteFieldConfiguration_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/fieldconfiguration/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteFieldConfiguration( $self, %options ) {
    my $tx = $self->_build_deleteFieldConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateFieldConfiguration >>

  my $res = $client->updateFieldConfiguration()->get;

Update field configuration

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the field configuration.

=item C<< name >>

The name of the field configuration. Must be unique.

=back

Returns a L<<  >>.

=cut

sub _build_updateFieldConfiguration_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/fieldconfiguration/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::FieldConfigurationDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateFieldConfiguration( $self, %options ) {
    my $tx = $self->_build_updateFieldConfiguration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFieldConfigurationItems >>

  my $res = $client->getFieldConfigurationItems()->get;

Get field configuration items

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanFieldConfigurationItem >>.

=cut

sub _build_getFieldConfigurationItems_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/fieldconfiguration/{id}/fields' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFieldConfigurationItems( $self, %options ) {
    my $tx = $self->_build_getFieldConfigurationItems_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanFieldConfigurationItem->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateFieldConfigurationItems >>

  my $res = $client->updateFieldConfigurationItems()->get;

Update field configuration items

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration.

=back


=head3 Options

=over 4

=item C<< fieldConfigurationItems >>

Details of fields in a field configuration.

=back

Returns a L<<  >>.

=cut

sub _build_updateFieldConfigurationItems_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/fieldconfiguration/{id}/fields' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::FieldConfigurationItemsDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateFieldConfigurationItems( $self, %options ) {
    my $tx = $self->_build_updateFieldConfigurationItems_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllFieldConfigurationSchemes >>

  my $res = $client->getAllFieldConfigurationSchemes()->get;

Get all field configuration schemes

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of field configuration scheme IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>.

=back


Returns a L<< JIRA::API::PageBeanFieldConfigurationScheme >>.

=cut

sub _build_getAllFieldConfigurationSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/fieldconfigurationscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllFieldConfigurationSchemes( $self, %options ) {
    my $tx = $self->_build_getAllFieldConfigurationSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanFieldConfigurationScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createFieldConfigurationScheme >>

  my $res = $client->createFieldConfigurationScheme()->get;

Create field configuration scheme

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the field configuration scheme.

=item C<< name >>

The name of the field configuration scheme. The name must be unique.

=back

Returns a L<< JIRA::API::FieldConfigurationScheme >>.

=cut

sub _build_createFieldConfigurationScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/fieldconfigurationscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateFieldConfigurationSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createFieldConfigurationScheme( $self, %options ) {
    my $tx = $self->_build_createFieldConfigurationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FieldConfigurationScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFieldConfigurationSchemeMappings >>

  my $res = $client->getFieldConfigurationSchemeMappings()->get;

Get field configuration issue type items

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< fieldConfigurationSchemeId >>

The list of field configuration scheme IDs. To include multiple field configuration schemes separate IDs with ampersand: C<fieldConfigurationSchemeId=10000&fieldConfigurationSchemeId=10001>.

=back


Returns a L<< JIRA::API::PageBeanFieldConfigurationIssueTypeItem >>.

=cut

sub _build_getFieldConfigurationSchemeMappings_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/fieldconfigurationscheme/mapping';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'fieldConfigurationSchemeId' => delete $options{'fieldConfigurationSchemeId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFieldConfigurationSchemeMappings( $self, %options ) {
    my $tx = $self->_build_getFieldConfigurationSchemeMappings_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanFieldConfigurationIssueTypeItem->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if no field configuration schemes are found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFieldConfigurationSchemeProjectMapping >>

  my $res = $client->getFieldConfigurationSchemeProjectMapping()->get;

Get field configuration schemes for projects

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< projectId >>

The list of project IDs. To include multiple projects, separate IDs with ampersand: C<projectId=10000&projectId=10001>.

=back


Returns a L<< JIRA::API::PageBeanFieldConfigurationSchemeProjects >>.

=cut

sub _build_getFieldConfigurationSchemeProjectMapping_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $path = '/rest/api/3/fieldconfigurationscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
              'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFieldConfigurationSchemeProjectMapping( $self, %options ) {
    my $tx = $self->_build_getFieldConfigurationSchemeProjectMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanFieldConfigurationSchemeProjects->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignFieldConfigurationSchemeToProject >>

  my $res = $client->assignFieldConfigurationSchemeToProject()->get;

Assign field configuration scheme to project

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< fieldConfigurationSchemeId >>

The ID of the field configuration scheme. If the field configuration scheme ID is C<null>, the operation assigns the default field configuration scheme.

=item C<< projectId >>

The ID of the project.

=back

Returns a L<<  >>.

=cut

sub _build_assignFieldConfigurationSchemeToProject_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/fieldconfigurationscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::FieldConfigurationSchemeProjectAssociation->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignFieldConfigurationSchemeToProject( $self, %options ) {
    my $tx = $self->_build_assignFieldConfigurationSchemeToProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the project is not a classic project.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the project is missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteFieldConfigurationScheme >>

  my $res = $client->deleteFieldConfigurationScheme()->get;

Delete field configuration scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration scheme.

=back


Returns a L<<  >>.

=cut

sub _build_deleteFieldConfigurationScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/fieldconfigurationscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteFieldConfigurationScheme( $self, %options ) {
    my $tx = $self->_build_deleteFieldConfigurationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateFieldConfigurationScheme >>

  my $res = $client->updateFieldConfigurationScheme()->get;

Update field configuration scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration scheme.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the field configuration scheme.

=item C<< name >>

The name of the field configuration scheme. The name must be unique.

=back

Returns a L<<  >>.

=cut

sub _build_updateFieldConfigurationScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/fieldconfigurationscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateFieldConfigurationSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateFieldConfigurationScheme( $self, %options ) {
    my $tx = $self->_build_updateFieldConfigurationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setFieldConfigurationSchemeMapping >>

  my $res = $client->setFieldConfigurationSchemeMapping()->get;

Assign issue types to field configurations

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration scheme.

=back


=head3 Options

=over 4

=item C<< mappings >>

Field configuration to issue type mappings.

=back

Returns a L<<  >>.

=cut

sub _build_setFieldConfigurationSchemeMapping_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/fieldconfigurationscheme/{id}/mapping' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::AssociateFieldConfigurationsWithIssueTypesRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setFieldConfigurationSchemeMapping( $self, %options ) {
    my $tx = $self->_build_setFieldConfigurationSchemeMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration scheme, the field configuration, or the issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeIssueTypesFromGlobalFieldConfigurationScheme >>

  my $res = $client->removeIssueTypesFromGlobalFieldConfigurationScheme()->get;

Remove issue types from field configuration scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the field configuration scheme.

=back


=head3 Options

=over 4

=item C<< issueTypeIds >>

The list of issue type IDs. Must contain unique values not longer than 255 characters and not be empty. Maximum of 100 IDs.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_removeIssueTypesFromGlobalFieldConfigurationScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/fieldconfigurationscheme/{id}/mapping/delete' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeIdsToRemove->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub removeIssueTypesFromGlobalFieldConfigurationScheme( $self, %options ) {
    my $tx = $self->_build_removeIssueTypesFromGlobalFieldConfigurationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the field configuration scheme or the issue types are not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFilters >>

  my $res = $client->getFilters()->get;

Get filters

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=back


Returns an array of L<< JIRA::API::Filter >>.

=cut

sub _build_getFilters_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/filter';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFilters( $self, %options ) {
    my $tx = $self->_build_getFilters_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Filter->new($_),
 } $payload->@* ],

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createFilter >>

  my $res = $client->createFilter()->get;

Create filter

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=item B<< overrideSharePermissions >>

EXPERIMENTAL: Whether share permissions are overridden to enable filters with any share permissions to be created. Available to users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=back


=head3 Options

=over 4

=item C<< description >>

A description of the filter.

=item C<< editPermissions >>

The groups and projects that can edit the filter.

=item C<< favourite >>

Whether the filter is selected as a favorite.

=item C<< favouritedCount >>

The count of how many users have selected this filter as a favorite, including the filter owner.

=item C<< id >>

The unique identifier for the filter.

=item C<< jql >>

The JQL query for the filter. For example, I<project = SSP AND issuetype = Bug>.

=item C<< name >>

The name of the filter. Must be unique.

=item C<< owner >>

The user who owns the filter. This is defaulted to the creator of the filter, however Jira administrators can change the owner of a shared filter in the admin settings.

=item C<< searchUrl >>

A URL to view the filter results in Jira, using the L<Search for issues using JQL|#api-rest-api-3-filter-search-get> operation with the filter's JQL string to return the filter results. For example, I<https://your-domain.atlassian.net/rest/api/3/search?jql=project+%3D+SSP+AND+issuetype+%3D+Bug>.

=item C<< self >>

The URL of the filter.

=item C<< sharePermissions >>

The groups and projects that the filter is shared with.

=item C<< sharedUsers >>

A paginated list of the users that the filter is shared with. This includes users that are members of the groups or can browse the projects that the filter is shared with.

=item C<< subscriptions >>

A paginated list of the users that are subscribed to the filter.

=item C<< viewUrl >>

A URL to view the filter results in Jira, using the ID of the filter. For example, I<https://your-domain.atlassian.net/issues/?filter=10100>.

=back

Returns a L<< JIRA::API::Filter >>.

=cut

sub _build_createFilter_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/filter';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'overrideSharePermissions' => delete $options{'overrideSharePermissions'},
    );

    my $request = JIRA::API::Filter->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createFilter( $self, %options ) {
    my $tx = $self->_build_createFilter_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Filter->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request object is invalid. For example, the `name` is not unique or the project ID is not specified for a project role share permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDefaultShareScope >>

  my $res = $client->getDefaultShareScope()->get;

Get default share scope

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::DefaultShareScope >>.

=cut

sub _build_getDefaultShareScope_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/filter/defaultShareScope';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDefaultShareScope( $self, %options ) {
    my $tx = $self->_build_getDefaultShareScope_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::DefaultShareScope->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setDefaultShareScope >>

  my $res = $client->setDefaultShareScope()->get;

Set default share scope

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< scope >>

The scope of the default sharing for new filters and dashboards:

=over

=item *

C<AUTHENTICATED> Shared with all logged-in users.


=item *

C<GLOBAL> Shared with all logged-in users. This shows as C<AUTHENTICATED> in the response.


=item *

C<PRIVATE> Not shared with any users.


=back

=back

Returns a L<< JIRA::API::DefaultShareScope >>.

=cut

sub _build_setDefaultShareScope_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/filter/defaultShareScope';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DefaultShareScope->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setDefaultShareScope( $self, %options ) {
    my $tx = $self->_build_setDefaultShareScope_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::DefaultShareScope->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if an invalid scope is set.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFavouriteFilters >>

  my $res = $client->getFavouriteFilters()->get;

Get favorite filters

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=back


Returns an array of L<< JIRA::API::Filter >>.

=cut

sub _build_getFavouriteFilters_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/filter/favourite';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFavouriteFilters( $self, %options ) {
    my $tx = $self->_build_getFavouriteFilters_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Filter->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getMyFilters >>

  my $res = $client->getMyFilters()->get;

Get my filters

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=item B<< includeFavourites >>

Include the user's favorite filters in the response.

=back


Returns an array of L<< JIRA::API::Filter >>.

=cut

sub _build_getMyFilters_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/filter/my';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'includeFavourites' => delete $options{'includeFavourites'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getMyFilters( $self, %options ) {
    my $tx = $self->_build_getMyFilters_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Filter->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFiltersPaginated >>

  my $res = $client->getFiltersPaginated()->get;

Search for filters

=head3 Parameters

=over 4

=item B<< filterName >>

String used to perform a case-insensitive partial match with C<name>.

=item B<< accountId >>

User account ID used to return filters with the matching C<owner.accountId>. This parameter cannot be used with C<owner>.

=item B<< owner >>

This parameter is deprecated because of privacy changes. Use C<accountId> instead. See the L<migration guide|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details. User name used to return filters with the matching C<owner.name>. This parameter cannot be used with C<accountId>.

=item B<< groupname >>

As a group's name can change, use of C<groupId> is recommended to identify a group. Group name used to returns filters that are shared with a group that matches C<sharePermissions.group.groupname>. This parameter cannot be used with the C<groupId> parameter.

=item B<< groupId >>

Group ID used to returns filters that are shared with a group that matches C<sharePermissions.group.groupId>. This parameter cannot be used with the C<groupname> parameter.

=item B<< projectId >>

Project ID used to returns filters that are shared with a project that matches C<sharePermissions.project.id>.

=item B<< id >>

The list of filter IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>. Do not exceed 200 filter IDs.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<description> Sorts by filter description. Note that this sorting works independently of whether the expand to display the description field is in use.


=item *

C<favourite_count> Sorts by the count of how many users have this filter as a favorite.


=item *

C<is_favourite> Sorts by whether the filter is marked as a favorite.


=item *

C<id> Sorts by filter ID.


=item *

C<name> Sorts by filter name.


=item *

C<owner> Sorts by the ID of the filter owner.


=item *

C<is_shared> Sorts by whether the filter is shared.


=back

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<description> Returns the description of the filter.


=item *

C<favourite> Returns an indicator of whether the user has set the filter as a favorite.


=item *

C<favouritedCount> Returns a count of how many users have set this filter as a favorite.


=item *

C<jql> Returns the JQL query that the filter uses.


=item *

C<owner> Returns the owner of the filter.


=item *

C<searchUrl> Returns a URL to perform the filter's JQL query.


=item *

C<sharePermissions> Returns the share permissions defined for the filter.


=item *

C<editPermissions> Returns the edit permissions defined for the filter.


=item *

C<isWritable> Returns whether the current user has permission to edit the filter.


=item *

C<subscriptions> Returns the users that are subscribed to the filter.


=item *

C<viewUrl> Returns a URL to view the filter.


=back

=item B<< overrideSharePermissions >>

EXPERIMENTAL: Whether share permissions are overridden to enable filters with any share permissions to be returned. Available to users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=back


Returns a L<< JIRA::API::PageBeanFilterDetails >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getFiltersPaginated_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/filter/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'filterName' => delete $options{'filterName'},
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'owner' => delete $options{'owner'},
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'projectId' => delete $options{'projectId'},
        maybe 'id' => delete $options{'id'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'overrideSharePermissions' => delete $options{'overrideSharePermissions'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFiltersPaginated( $self, %options ) {
    my $tx = $self->_build_getFiltersPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanFilterDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `owner` and `accountId` are provided. * `expand` includes an invalid value. * `orderBy` is invalid. * `id` identifies more than 200 filter IDs.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteFilter >>

  my $res = $client->deleteFilter()->get;

Delete filter

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter to delete.

=back



=cut

sub _build_deleteFilter_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteFilter( $self, %options ) {
    my $tx = $self->_build_deleteFilter_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the filter is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the user does not have permission to delete the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFilter >>

  my $res = $client->getFilter()->get;

Get filter

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter to return.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=item B<< overrideSharePermissions >>

EXPERIMENTAL: Whether share permissions are overridden to enable filters with any share permissions to be returned. Available to users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=back


Returns a L<< JIRA::API::Filter >>.

=cut

sub _build_getFilter_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'overrideSharePermissions' => delete $options{'overrideSharePermissions'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFilter( $self, %options ) {
    my $tx = $self->_build_getFilter_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Filter->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the filter is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateFilter >>

  my $res = $client->updateFilter()->get;

Update filter

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter to update.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=item B<< overrideSharePermissions >>

EXPERIMENTAL: Whether share permissions are overridden to enable the addition of any share permissions to filters. Available to users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=back


=head3 Options

=over 4

=item C<< description >>

A description of the filter.

=item C<< editPermissions >>

The groups and projects that can edit the filter.

=item C<< favourite >>

Whether the filter is selected as a favorite.

=item C<< favouritedCount >>

The count of how many users have selected this filter as a favorite, including the filter owner.

=item C<< id >>

The unique identifier for the filter.

=item C<< jql >>

The JQL query for the filter. For example, I<project = SSP AND issuetype = Bug>.

=item C<< name >>

The name of the filter. Must be unique.

=item C<< owner >>

The user who owns the filter. This is defaulted to the creator of the filter, however Jira administrators can change the owner of a shared filter in the admin settings.

=item C<< searchUrl >>

A URL to view the filter results in Jira, using the L<Search for issues using JQL|#api-rest-api-3-filter-search-get> operation with the filter's JQL string to return the filter results. For example, I<https://your-domain.atlassian.net/rest/api/3/search?jql=project+%3D+SSP+AND+issuetype+%3D+Bug>.

=item C<< self >>

The URL of the filter.

=item C<< sharePermissions >>

The groups and projects that the filter is shared with.

=item C<< sharedUsers >>

A paginated list of the users that the filter is shared with. This includes users that are members of the groups or can browse the projects that the filter is shared with.

=item C<< subscriptions >>

A paginated list of the users that are subscribed to the filter.

=item C<< viewUrl >>

A URL to view the filter results in Jira, using the ID of the filter. For example, I<https://your-domain.atlassian.net/issues/?filter=10100>.

=back

Returns a L<< JIRA::API::Filter >>.

=cut

sub _build_updateFilter_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'overrideSharePermissions' => delete $options{'overrideSharePermissions'},
    );

    my $request = JIRA::API::Filter->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateFilter( $self, %options ) {
    my $tx = $self->_build_updateFilter_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Filter->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request object is invalid. For example, the `name` is not unique or the project ID is not specified for a project role share permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< resetColumns >>

  my $res = $client->resetColumns()->get;

Reset columns

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=back



=cut

sub _build_resetColumns_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/columns' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub resetColumns( $self, %options ) {
    my $tx = $self->_build_resetColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if: * the filter is not found. * the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getColumns >>

  my $res = $client->getColumns()->get;

Get columns

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=back


Returns an array of L<< JIRA::API::ColumnItem >>.

=cut

sub _build_getColumns_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/columns' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getColumns( $self, %options ) {
    my $tx = $self->_build_getColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ColumnItem->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if a column configuration is not set for the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setColumns >>

  my $res = $client->setColumns()->get;

Set columns

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=back


Returns a L<<  >>.

=cut

sub _build_setColumns_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/columns' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => '*/*',
        }
        # XXX Need to fill the body
        # => $body,
    );

    return $tx
}


sub setColumns( $self, %options ) {
    my $tx = $self->_build_setColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * a non-navigable field is set as a column. * the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the requesting user is not an owner of the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteFavouriteForFilter >>

  my $res = $client->deleteFavouriteForFilter()->get;

Remove filter as favorite

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=back


Returns a L<< JIRA::API::Filter >>.

=cut

sub _build_deleteFavouriteForFilter_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/favourite' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteFavouriteForFilter( $self, %options ) {
    my $tx = $self->_build_deleteFavouriteForFilter_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Filter->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the filter is not found. * the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setFavouriteForFilter >>

  my $res = $client->setFavouriteForFilter()->get;

Add filter as favorite

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about filter in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<sharedUsers> Returns the users that the filter is shared with. This includes users that can browse projects that the filter is shared with. If you don't specify C<sharedUsers>, then the C<sharedUsers> object is returned but it doesn't list any users. The list of users returned is limited to 1000, to access additional users append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 users, use C<?expand=sharedUsers[1001:2000]>.


=item *

C<subscriptions> Returns the users that are subscribed to the filter. If you don't specify C<subscriptions>, the C<subscriptions> object is returned but it doesn't list any subscriptions. The list of subscriptions returned is limited to 1000, to access additional subscriptions append C<[start-index:end-index]> to the expand request. For example, to access the next 1000 subscriptions, use C<?expand=subscriptions[1001:2000]>.


=back

=back


Returns a L<< JIRA::API::Filter >>.

=cut

sub _build_setFavouriteForFilter_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/favourite' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub setFavouriteForFilter( $self, %options ) {
    my $tx = $self->_build_setFavouriteForFilter_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Filter->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the filter is not found. * the user does not have permission to favorite the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< changeFilterOwner >>

  my $res = $client->changeFilterOwner()->get;

Change filter owner

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter to update.

=back


=head3 Options

=over 4

=item C<< accountId >>

The account ID of the new owner.

=back

Returns a L<<  >>.

=cut

sub _build_changeFilterOwner_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/owner' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ChangeFilterOwner->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub changeFilterOwner( $self, %options ) {
    my $tx = $self->_build_changeFilterOwner_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned when: * The new owner of the filter owns a filter with the same name. * An attempt is made to change owner of the default filter.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the requesting user is not an owner of the filter or does not have *Administer Jira* global permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the filter or the new owner of the filter is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getSharePermissions >>

  my $res = $client->getSharePermissions()->get;

Get share permissions

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=back


Returns an array of L<< JIRA::API::SharePermission >>.

=cut

sub _build_getSharePermissions_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/permission' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getSharePermissions( $self, %options ) {
    my $tx = $self->_build_getSharePermissions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::SharePermission->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the filter is not found. * the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addSharePermission >>

  my $res = $client->addSharePermission()->get;

Add share permission

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=back


=head3 Options

=over 4

=item C<< accountId >>

The user account ID that the filter is shared with. For a request, specify the C<accountId> property for the user.

=item C<< groupId >>

The ID of the group, which uniquely identifies the group across all Atlassian products.For example, I<952d12c3-5b5b-4d04-bb32-44d383afc4b2>. Cannot be provided with C<groupname>.

=item C<< groupname >>

The name of the group to share the filter with. Set C<type> to C<group>. Please note that the name of a group is mutable, to reliably identify a group use C<groupId>.

=item C<< projectId >>

The ID of the project to share the filter with. Set C<type> to C<project>.

=item C<< projectRoleId >>

The ID of the project role to share the filter with. Set C<type> to C<projectRole> and the C<projectId> for the project that the role is in.

=item C<< rights >>

The rights for the share permission.

=item C<< type >>

The type of the share permission.Specify the type as follows:

=over

=item *

C<user> Share with a user.


=item *

C<group> Share with a group. Specify C<groupname> as well.


=item *

C<project> Share with a project. Specify C<projectId> as well.


=item *

C<projectRole> Share with a project role in a project. Specify C<projectId> and C<projectRoleId> as well.


=item *

C<global> Share globally, including anonymous users. If set, this type overrides all existing share permissions and must be deleted before any non-global share permissions is set.


=item *

C<authenticated> Share with all logged-in users. This shows as C<loggedin> in the response. If set, this type overrides all existing share permissions and must be deleted before any non-global share permissions is set.


=back

=back

Returns an array of L<< JIRA::API::SharePermission >>.

=cut

sub _build_addSharePermission_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/permission' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::SharePermissionInputBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addSharePermission( $self, %options ) {
    my $tx = $self->_build_addSharePermission_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::SharePermission->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the request object is invalid. For example, it contains an invalid type, the ID does not match the type, or the project or group is not found. * the user does not own the filter. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the filter is not found. * the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteSharePermission >>

  my $res = $client->deleteSharePermission()->get;

Delete share permission

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=item B<< permissionId >>

The ID of the share permission.

=back



=cut

sub _build_deleteSharePermission_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'permissionId'"
        unless exists $options{ 'permissionId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/permission/{permissionId}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'permissionId' => delete $options{'permissionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteSharePermission( $self, %options ) {
    my $tx = $self->_build_deleteSharePermission_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the filter is not found. * the user does not own the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getSharePermission >>

  my $res = $client->getSharePermission()->get;

Get share permission

=head3 Parameters

=over 4

=item B<< id >>

The ID of the filter.

=item B<< permissionId >>

The ID of the share permission.

=back


Returns a L<< JIRA::API::SharePermission >>.

=cut

sub _build_getSharePermission_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'permissionId'"
        unless exists $options{ 'permissionId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/filter/{id}/permission/{permissionId}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'permissionId' => delete $options{'permissionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getSharePermission( $self, %options ) {
    my $tx = $self->_build_getSharePermission_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SharePermission->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the filter is not found. * the permission is not found. * the user does not have permission to view the filter.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeGroup >>

  my $res = $client->removeGroup()->get;

Remove group

=head3 Parameters

=over 4

=item B<< groupname >>

=item B<< groupId >>

The ID of the group. This parameter cannot be used with the C<groupname> parameter.

=item B<< swapGroup >>

As a group's name can change, use of C<swapGroupId> is recommended to identify a group.

The group to transfer restrictions to. Only comments and worklogs are transferred. If restrictions are not transferred, comments and worklogs are inaccessible after the deletion. This parameter cannot be used with the C<swapGroupId> parameter.

=item B<< swapGroupId >>

The ID of the group to transfer restrictions to. Only comments and worklogs are transferred. If restrictions are not transferred, comments and worklogs are inaccessible after the deletion. This parameter cannot be used with the C<swapGroup> parameter.

=back



=cut

sub _build_removeGroup_request( $self, %options ) {
    my $method = 'DELETE';
    my $path = '/rest/api/3/group';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'swapGroup' => delete $options{'swapGroup'},
        maybe 'swapGroupId' => delete $options{'swapGroupId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeGroup( $self, %options ) {
    my $tx = $self->_build_removeGroup_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the group name is not specified.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing from the request.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the group is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getGroup >>

  my $res = $client->getGroup()->get;

Get group

=head3 Parameters

=over 4

=item B<< groupname >>

As a group's name can change, use of C<groupId> is recommended to identify a group.

The name of the group. This parameter cannot be used with the C<groupId> parameter.

=item B<< groupId >>

The ID of the group. This parameter cannot be used with the C<groupName> parameter.

=item B<< expand >>

List of fields to expand.

=back


Returns a L<< JIRA::API::Group >>.

=cut

sub _build_getGroup_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/group';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getGroup( $self, %options ) {
    my $tx = $self->_build_getGroup_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Group->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the group name is not specified.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the calling user does not have the Administer Jira global permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the group is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createGroup >>

  my $res = $client->createGroup()->get;

Create group

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< name >>

The name of the group.

=back

Returns a L<< JIRA::API::Group >>.

=cut

sub _build_createGroup_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/group';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::AddGroupBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createGroup( $self, %options ) {
    my $tx = $self->_build_createGroup_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Group->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if group name is not specified or the group name is in use.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkGetGroups >>

  my $res = $client->bulkGetGroups()->get;

Bulk get groups

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< groupId >>

The ID of a group. To specify multiple IDs, pass multiple C<groupId> parameters. For example, C<groupId=5b10a2844c20165700ede21g&groupId=5b10ac8d82e05b22cc7d4ef5>.

=item B<< groupName >>

The name of a group. To specify multiple names, pass multiple C<groupName> parameters. For example, C<groupName=administrators&groupName=jira-software-users>.

=item B<< accessType >>

The access level of a group. Valid values: 'site-admin', 'admin', 'user'.

=item B<< applicationKey >>

The application key of the product user groups to search for. Valid values: 'jira-servicedesk', 'jira-software', 'jira-product-discovery', 'jira-core'.

=back


Returns a L<< JIRA::API::PageBeanGroupDetails >>.

=cut

sub _build_bulkGetGroups_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/group/bulk';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'groupName' => delete $options{'groupName'},
        maybe 'accessType' => delete $options{'accessType'},
        maybe 'applicationKey' => delete $options{'applicationKey'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub bulkGetGroups( $self, %options ) {
    my $tx = $self->_build_bulkGetGroups_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanGroupDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 500 ) {
            # Returned if the group with the given access level can't be retrieved.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUsersFromGroup >>

  my $res = $client->getUsersFromGroup()->get;

Get users from group

=head3 Parameters

=over 4

=item B<< groupname >>

As a group's name can change, use of C<groupId> is recommended to identify a group.

The name of the group. This parameter cannot be used with the C<groupId> parameter.

=item B<< groupId >>

The ID of the group. This parameter cannot be used with the C<groupName> parameter.

=item B<< includeInactiveUsers >>

Include inactive users.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanUserDetails >>.

=cut

sub _build_getUsersFromGroup_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/group/member';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'includeInactiveUsers' => delete $options{'includeInactiveUsers'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUsersFromGroup( $self, %options ) {
    my $tx = $self->_build_getUsersFromGroup_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanUserDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the group name is not specified.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the calling user does not have the Administer Jira global permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the group is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeUserFromGroup >>

  my $res = $client->removeUserFromGroup()->get;

Remove user from group

=head3 Parameters

=over 4

=item B<< groupname >>

As a group's name can change, use of C<groupId> is recommended to identify a group.

The name of the group. This parameter cannot be used with the C<groupId> parameter.

=item B<< groupId >>

The ID of the group. This parameter cannot be used with the C<groupName> parameter.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=back



=cut

sub _build_removeUserFromGroup_request( $self, %options ) {
    croak "Missing required parameter 'accountId'"
        unless exists $options{ 'accountId' };

    my $method = 'DELETE';
    my $path = '/rest/api/3/group/user';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'username' => delete $options{'username'},
              'accountId' => delete $options{'accountId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeUserFromGroup( $self, %options ) {
    my $tx = $self->_build_removeUserFromGroup_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if: * `groupName` is missing. * `accountId` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing from the request.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the group or user are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addUserToGroup >>

  my $res = $client->addUserToGroup()->get;

Add user to group

=head3 Parameters

=over 4

=item B<< groupname >>

As a group's name can change, use of C<groupId> is recommended to identify a group.

The name of the group. This parameter cannot be used with the C<groupId> parameter.

=item B<< groupId >>

The ID of the group. This parameter cannot be used with the C<groupName> parameter.

=back


=head3 Options

=over 4

=item C<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item C<< name >>

This property is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back

Returns a L<< JIRA::API::Group >>.

=cut

sub _build_addUserToGroup_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/group/user';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'groupname' => delete $options{'groupname'},
        maybe 'groupId' => delete $options{'groupId'},
    );

    my $request = JIRA::API::UpdateUserToGroupBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addUserToGroup( $self, %options ) {
    my $tx = $self->_build_addUserToGroup_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Group->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `groupname` is not provided. * `accountId` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing from the request.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the calling user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the group or user are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findGroups >>

  my $res = $client->findGroups()->get;

Find groups

=head3 Parameters

=over 4

=item B<< accountId >>

This parameter is deprecated, setting it does not affect the results. To find groups containing a particular user, use L<Get user groups|#api-rest-api-3-user-groups-get>.

=item B<< query >>

The string to find in group names.

=item B<< exclude >>

As a group's name can change, use of C<excludeGroupIds> is recommended to identify a group.

A group to exclude from the result. To exclude multiple groups, provide an ampersand-separated list. For example, C<exclude=group1&exclude=group2>. This parameter cannot be used with the C<excludeGroupIds> parameter.

=item B<< excludeId >>

A group ID to exclude from the result. To exclude multiple groups, provide an ampersand-separated list. For example, C<excludeId=group1-id&excludeId=group2-id>. This parameter cannot be used with the C<excludeGroups> parameter.

=item B<< maxResults >>

The maximum number of groups to return. The maximum number of groups that can be returned is limited by the system property C<jira.ajax.autocomplete.limit>.

=item B<< caseInsensitive >>

Whether the search for groups should be case insensitive.

=item B<< userName >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back


Returns a L<< JIRA::API::FoundGroups >>.

=cut

sub _build_findGroups_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/groups/picker';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'query' => delete $options{'query'},
        maybe 'exclude' => delete $options{'exclude'},
        maybe 'excludeId' => delete $options{'excludeId'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'caseInsensitive' => delete $options{'caseInsensitive'},
        maybe 'userName' => delete $options{'userName'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findGroups( $self, %options ) {
    my $tx = $self->_build_findGroups_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FoundGroups->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUsersAndGroups >>

  my $res = $client->findUsersAndGroups()->get;

Find users and groups

=head3 Parameters

=over 4

=item B<< query >>

The search string.

=item B<< maxResults >>

The maximum number of items to return in each list.

=item B<< showAvatar >>

Whether the user avatar should be returned. If an invalid value is provided, the default value is used.

=item B<< fieldId >>

The custom field ID of the field this request is for.

=item B<< projectId >>

The ID of a project that returned users and groups must have permission to view. To include multiple projects, provide an ampersand-separated list. For example, C<projectId=10000&projectId=10001>. This parameter is only used when C<fieldId> is present.

=item B<< issueTypeId >>

The ID of an issue type that returned users and groups must have permission to view. To include multiple issue types, provide an ampersand-separated list. For example, C<issueTypeId=10000&issueTypeId=10001>. Special values, such as C<-1> (all standard issue types) and C<-2> (all subtask issue types), are supported. This parameter is only used when C<fieldId> is present.

=item B<< avatarSize >>

The size of the avatar to return. If an invalid value is provided, the default value is used.

=item B<< caseInsensitive >>

Whether the search for groups should be case insensitive.

=item B<< excludeConnectAddons >>

Whether Connect app users and groups should be excluded from the search results. If an invalid value is provided, the default value is used.

=back


Returns a L<< JIRA::API::FoundUsersAndGroups >>.

=cut

sub _build_findUsersAndGroups_request( $self, %options ) {
    croak "Missing required parameter 'query'"
        unless exists $options{ 'query' };

    my $method = 'GET';
    my $path = '/rest/api/3/groupuserpicker';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'query' => delete $options{'query'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'showAvatar' => delete $options{'showAvatar'},
        maybe 'fieldId' => delete $options{'fieldId'},
        maybe 'projectId' => delete $options{'projectId'},
        maybe 'issueTypeId' => delete $options{'issueTypeId'},
        maybe 'avatarSize' => delete $options{'avatarSize'},
        maybe 'caseInsensitive' => delete $options{'caseInsensitive'},
        maybe 'excludeConnectAddons' => delete $options{'excludeConnectAddons'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUsersAndGroups( $self, %options ) {
    my $tx = $self->_build_findUsersAndGroups_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FoundUsersAndGroups->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the query parameter is not provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getLicense >>

  my $res = $client->getLicense()->get;

Get license

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::License >>.

=cut

sub _build_getLicense_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/instance/license';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getLicense( $self, %options ) {
    my $tx = $self->_build_getLicense_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::License->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssue >>

  my $res = $client->createIssue()->get;

Create issue

=head3 Parameters

=over 4

=item B<< updateHistory >>

Whether the project in which the issue is created is added to the user's B<Recently viewed> project list, as shown under B<Projects> in Jira. When provided, the issue type and request type are added to the user's history for a project. These values are then used to provide defaults on the issue create screen.

=back


=head3 Options

=over 4

=item C<< fields >>

List of issue screen fields to update, specifying the sub-field to update and its value for each field. This field provides a straightforward option when setting a sub-field. When multiple sub-fields or other operations are required, use C<update>. Fields included in here cannot be included in C<update>.

=item C<< historyMetadata >>

Additional issue history details.

=item C<< properties >>

Details of issue properties to be add or update.

=item C<< transition >>

Details of a transition. Required when performing a transition, optional when creating or editing an issue.

=item C<< update >>

A Map containing the field field name and a list of operations to perform on the issue screen field. Note that fields included in here cannot be included in C<fields>.

=back

Returns a L<< JIRA::API::CreatedIssue >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_createIssue_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issue';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'updateHistory' => delete $options{'updateHistory'},
    );

    my $request = JIRA::API::IssueUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssue( $self, %options ) {
    my $tx = $self->_build_createIssue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CreatedIssue->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request: * is missing required fields. * contains invalid field values. * contains fields that cannot be set for the issue type. * is by a user who does not have the necessary permission. * is to create a subtype in a project different that of the parent issue. * is for a subtask when the option to create subtasks is disabled. * is invalid for any other reason.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssues >>

  my $res = $client->createIssues()->get;

Bulk create issue

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< issueUpdates >>

=back

Returns a L<< JIRA::API::CreatedIssues >>.
Returns a L<< JIRA::API::CreatedIssues >>.

=cut

sub _build_createIssues_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issue/bulk';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssuesUpdateBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssues( $self, %options ) {
    my $tx = $self->_build_createIssues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if any of the issue or subtask creation requests were successful. A request may be unsuccessful when it: * is missing required fields. * contains invalid field values. * contains fields that cannot be set for the issue type. * is by a user who does not have the necessary permission. * is to create a subtype in a project different that of the parent issue. * is for a subtask when the option to create subtasks is disabled. * is invalid for any other reason.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CreatedIssues->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if all requests are invalid. Requests may be unsuccessful when they: * are missing required fields. * contain invalid field values. * contain fields that cannot be set for the issue type. * are by a user who does not have the necessary permission. * are to create a subtype in a project different that of the parent issue. * is for a subtask when the option to create subtasks is disabled. * are invalid for any other reason.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::CreatedIssues->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCreateIssueMeta >>

  my $res = $client->getCreateIssueMeta()->get;

Get create issue metadata

=head3 Parameters

=over 4

=item B<< projectIds >>

List of project IDs. This parameter accepts a comma-separated list. Multiple project IDs can also be provided using an ampersand-separated list. For example, C<projectIds=10000,10001&projectIds=10020,10021>. This parameter may be provided with C<projectKeys>.

=item B<< projectKeys >>

List of project keys. This parameter accepts a comma-separated list. Multiple project keys can also be provided using an ampersand-separated list. For example, C<projectKeys=proj1,proj2&projectKeys=proj3>. This parameter may be provided with C<projectIds>.

=item B<< issuetypeIds >>

List of issue type IDs. This parameter accepts a comma-separated list. Multiple issue type IDs can also be provided using an ampersand-separated list. For example, C<issuetypeIds=10000,10001&issuetypeIds=10020,10021>. This parameter may be provided with C<issuetypeNames>.

=item B<< issuetypeNames >>

List of issue type names. This parameter accepts a comma-separated list. Multiple issue type names can also be provided using an ampersand-separated list. For example, C<issuetypeNames=name1,name2&issuetypeNames=name3>. This parameter may be provided with C<issuetypeIds>.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about issue metadata in the response. This parameter accepts C<projects.issuetypes.fields>, which returns information about the fields in the issue creation screen for each issue type. Fields hidden from the screen are not returned. Use the information to populate the C<fields> and C<update> fields in L<Create issue|#api-rest-api-3-issue-post> and L<Create issues|#api-rest-api-3-issue-bulk-post>.

=back


Returns a L<< JIRA::API::IssueCreateMetadata >>.

=cut

sub _build_getCreateIssueMeta_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issue/createmeta';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'projectIds' => delete $options{'projectIds'},
        maybe 'projectKeys' => delete $options{'projectKeys'},
        maybe 'issuetypeIds' => delete $options{'issuetypeIds'},
        maybe 'issuetypeNames' => delete $options{'issuetypeNames'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getCreateIssueMeta( $self, %options ) {
    my $tx = $self->_build_getCreateIssueMeta_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueCreateMetadata->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssuePickerResource >>

  my $res = $client->getIssuePickerResource()->get;

Get issue picker suggestions

=head3 Parameters

=over 4

=item B<< query >>

A string to match against text fields in the issue such as title, description, or comments.

=item B<< currentJQL >>

A JQL query defining a list of issues to search for the query term. Note that C<username> and C<userkey> cannot be used as search terms for this parameter, due to privacy reasons. Use C<accountId> instead.

=item B<< currentIssueKey >>

The key of an issue to exclude from search results. For example, the issue the user is viewing when they perform this query.

=item B<< currentProjectId >>

The ID of a project that suggested issues must belong to.

=item B<< showSubTasks >>

Indicate whether to include subtasks in the suggestions list.

=item B<< showSubTaskParent >>

When C<currentIssueKey> is a subtask, whether to include the parent issue in the suggestions if it matches the query.

=back


Returns a L<< JIRA::API::IssuePickerSuggestions >>.

=cut

sub _build_getIssuePickerResource_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issue/picker';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'query' => delete $options{'query'},
        maybe 'currentJQL' => delete $options{'currentJQL'},
        maybe 'currentIssueKey' => delete $options{'currentIssueKey'},
        maybe 'currentProjectId' => delete $options{'currentProjectId'},
        maybe 'showSubTasks' => delete $options{'showSubTasks'},
        maybe 'showSubTaskParent' => delete $options{'showSubTaskParent'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssuePickerResource( $self, %options ) {
    my $tx = $self->_build_getIssuePickerResource_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssuePickerSuggestions->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkSetIssuesPropertiesList >>

  my $res = $client->bulkSetIssuesPropertiesList()->get;

Bulk set issues properties by list

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< entitiesIds >>

A list of entity property IDs.

=item C<< properties >>

A list of entity property keys and values.

=back

Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_bulkSetIssuesPropertiesList_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issue/properties';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueEntityProperties->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub bulkSetIssuesPropertiesList( $self, %options ) {
    my $tx = $self->_build_bulkSetIssuesPropertiesList_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the operation is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Return if the request is invalid or the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkSetIssuePropertiesByIssue >>

  my $res = $client->bulkSetIssuePropertiesByIssue()->get;

Bulk set issue properties by issue

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< issues >>

A list of issue IDs and their respective properties.

=back

Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_bulkSetIssuePropertiesByIssue_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issue/properties/multi';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::MultiIssueEntityProperties->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub bulkSetIssuePropertiesByIssue( $self, %options ) {
    my $tx = $self->_build_bulkSetIssuePropertiesByIssue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the operation is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Return if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Return if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkDeleteIssueProperty >>

  my $res = $client->bulkDeleteIssueProperty()->get;

Bulk delete issue property

=head3 Parameters

=over 4

=item B<< propertyKey >>

The key of the property.

=back


=head3 Options

=over 4

=item C<< currentValue >>

The value of properties to perform the bulk operation on.

=item C<< entityIds >>

List of issues to perform the bulk delete operation on.

=back

Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_bulkDeleteIssueProperty_request( $self, %options ) {
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/properties/{propertyKey}' );
    my $path = $template->process(
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueFilterForBulkPropertyDelete->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub bulkDeleteIssueProperty( $self, %options ) {
    my $tx = $self->_build_bulkDeleteIssueProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkSetIssueProperty >>

  my $res = $client->bulkSetIssueProperty()->get;

Bulk set issue property

=head3 Parameters

=over 4

=item B<< propertyKey >>

The key of the property. The maximum length is 255 characters.

=back


=head3 Options

=over 4

=item C<< expression >>

EXPERIMENTAL. The Jira expression to calculate the value of the property. The value of the expression must be an object that can be converted to JSON, such as a number, boolean, string, list, or map. The context variables available to the expression are C<issue> and C<user>. Issues for which the expression returns a value whose JSON representation is longer than 32768 characters are ignored.

=item C<< filter >>

The bulk operation filter.

=item C<< value >>

The value of the property. The value must be a L<valid|https://tools.ietf.org/html/rfc4627>, non-empty JSON blob. The maximum length is 32768 characters.

=back

Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_bulkSetIssueProperty_request( $self, %options ) {
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/properties/{propertyKey}' );
    my $path = $template->process(
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::BulkIssuePropertyUpdateRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub bulkSetIssueProperty( $self, %options ) {
    my $tx = $self->_build_bulkSetIssueProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIsWatchingIssueBulk >>

  my $res = $client->getIsWatchingIssueBulk()->get;

Get is watching issue bulk

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< issueIds >>

The list of issue IDs.

=back

Returns a L<< JIRA::API::BulkIssueIsWatching >>.

=cut

sub _build_getIsWatchingIssueBulk_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issue/watching';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueList->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getIsWatchingIssueBulk( $self, %options ) {
    my $tx = $self->_build_getIsWatchingIssueBulk_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::BulkIssueIsWatching->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssue >>

  my $res = $client->deleteIssue()->get;

Delete issue

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< deleteSubtasks >>

Whether the issue's subtasks are deleted when the issue is deleted.

=back



=cut

sub _build_deleteIssue_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'deleteSubtasks' => delete $options{'deleteSubtasks'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteIssue( $self, %options ) {
    my $tx = $self->_build_deleteIssue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the issue has subtasks and `deleteSubtasks` is not set to *true*.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to delete the issue.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssue >>

  my $res = $client->getIssue()->get;

Get issue

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< fields >>

A list of fields to return for the issue. This parameter accepts a comma-separated list. Use it to retrieve a subset of fields. Allowed values:

=over

=item *

C<*all> Returns all fields.


=item *

C<*navigable> Returns navigable fields.


=item *

Any issue field, prefixed with a minus to exclude.


=back

Examples:

=over

=item *

C<summary,comment> Returns only the summary and comments fields.


=item *

C<-description> Returns all (default) fields except description.


=item *

C<*navigable,-comment> Returns all navigable fields except comment.


=back

This parameter may be specified multiple times. For example, C<fields=field1,field2& fields=field3>.

Note: All fields are returned by default. This differs from L<Search for issues using JQL (GET)|#api-rest-api-3-search-get> and L<Search for issues using JQL (POST)|#api-rest-api-3-search-post> where the default is all navigable fields.

=item B<< fieldsByKeys >>

Whether fields in C<fields> are referenced by keys rather than IDs. This parameter is useful where fields have been added by a connect app and a field's key may differ from its ID.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about the issues in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<renderedFields> Returns field values rendered in HTML format.


=item *

C<names> Returns the display name of each field.


=item *

C<schema> Returns the schema describing a field type.


=item *

C<transitions> Returns all possible transitions for the issue.


=item *

C<editmeta> Returns information about how each field can be edited.


=item *

C<changelog> Returns a list of recent updates to an issue, sorted by date, starting from the most recent.


=item *

C<versionedRepresentations> Returns a JSON array for each version of a field's value, with the highest number representing the most recent version. Note: When included in the request, the C<fields> parameter is ignored.


=back

=item B<< properties >>

A list of issue properties to return for the issue. This parameter accepts a comma-separated list. Allowed values:

=over

=item *

C<*all> Returns all issue properties.


=item *

Any issue property key, prefixed with a minus to exclude.


=back

Examples:

=over

=item *

C<*all> Returns all properties.


=item *

C<*all,-prop1> Returns all properties except C<prop1>.


=item *

C<prop1,prop2> Returns C<prop1> and C<prop2> properties.


=back

This parameter may be specified multiple times. For example, C<properties=prop1,prop2& properties=prop3>.

=item B<< updateHistory >>

Whether the project in which the issue is created is added to the user's B<Recently viewed> project list, as shown under B<Projects> in Jira. This also populates the L<JQL issues search|#api-rest-api-3-search-get> C<lastViewed> field.

=back


Returns a L<< JIRA::API::IssueBean >>.

=cut

sub _build_getIssue_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'fields' => delete $options{'fields'},
        maybe 'fieldsByKeys' => delete $options{'fieldsByKeys'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'properties' => delete $options{'properties'},
        maybe 'updateHistory' => delete $options{'updateHistory'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssue( $self, %options ) {
    my $tx = $self->_build_getIssue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueBean->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< editIssue >>

  my $res = $client->editIssue()->get;

Edit issue

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< notifyUsers >>

Whether a notification email about the issue update is sent to all watchers. To disable the notification, administer Jira or administer project permissions are required. If the user doesn't have the necessary permission the request is ignored.

=item B<< overrideScreenSecurity >>

Whether screen security is overridden to enable hidden fields to be edited. Available to Connect app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> and Forge apps acting on behalf of users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=item B<< overrideEditableFlag >>

Whether screen security is overridden to enable uneditable fields to be edited. Available to Connect app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> and Forge apps acting on behalf of users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=back


=head3 Options

=over 4

=item C<< fields >>

List of issue screen fields to update, specifying the sub-field to update and its value for each field. This field provides a straightforward option when setting a sub-field. When multiple sub-fields or other operations are required, use C<update>. Fields included in here cannot be included in C<update>.

=item C<< historyMetadata >>

Additional issue history details.

=item C<< properties >>

Details of issue properties to be add or update.

=item C<< transition >>

Details of a transition. Required when performing a transition, optional when creating or editing an issue.

=item C<< update >>

A Map containing the field field name and a list of operations to perform on the issue screen field. Note that fields included in here cannot be included in C<fields>.

=back

Returns a L<<  >>.

=cut

sub _build_editIssue_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'notifyUsers' => delete $options{'notifyUsers'},
        maybe 'overrideScreenSecurity' => delete $options{'overrideScreenSecurity'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
    );

    my $request = JIRA::API::IssueUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub editIssue( $self, %options ) {
    my $tx = $self->_build_editIssue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the request body is missing. * the user does not have the necessary permission to edit one or more fields. * the request includes one or more fields that are not found or are not associated with the issue's edit screen. * the request includes an invalid transition.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user uses `overrideScreenSecurity` or `overrideEditableFlag` but doesn't have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignIssue >>

  my $res = $client->assignIssue()->get;

Assign issue

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue to be assigned.

=back


=head3 Options

=over 4

=item C<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>. Required in requests.

=item C<< accountType >>

The user account type. Can take the following values:

=over

=item *

C<atlassian> regular Atlassian user account


=item *

C<app> system account used for Connect applications and OAuth to represent external systems


=item *

C<customer> Jira Service Desk account representing an external service desk


=back

=item C<< active >>

Whether the user is active.

=item C<< applicationRoles >>

The application roles the user is assigned to.

=item C<< avatarUrls >>

The avatars of the user.

=item C<< displayName >>

The display name of the user. Depending on the user’s privacy setting, this may return an alternative value.

=item C<< emailAddress >>

The email address of the user. Depending on the user’s privacy setting, this may be returned as null.

=item C<< expand >>

Expand options that include additional user details in the response.

=item C<< groups >>

The groups that the user belongs to.

=item C<< key >>

This property is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item C<< locale >>

The locale of the user. Depending on the user’s privacy setting, this may be returned as null.

=item C<< name >>

This property is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item C<< self >>

The URL of the user.

=item C<< timeZone >>

The time zone specified in the user's profile. Depending on the user’s privacy setting, this may be returned as null.

=back

Returns a L<<  >>.

=cut

sub _build_assignIssue_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/assignee' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::User->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignIssue( $self, %options ) {
    my $tx = $self->_build_assignIssue_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the user is not found. * `name`, `key`, or `accountId` is missing. * more than one of `name`, `key`, and `accountId` are provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addAttachment >>

  my $res = $client->addAttachment()->get;

Add attachment

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue that attachments are added to.

=back


Returns an array of L<< JIRA::API::Attachment >>.

=cut

sub _build_addAttachment_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/attachments' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $body = delete $options{ body } // '';
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'multipart/form-data',
        }
        => form => $request->as_hash,
    );

    return $tx
}


sub addAttachment( $self, %options ) {
    my $tx = $self->_build_addAttachment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Attachment->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * the issue is not found. * the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 413 ) {
            # The attachments exceed the maximum attachment size for issues. See [Configuring file attachments](https://confluence.atlassian.com/x/wIXKM) for details.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getChangeLogs >>

  my $res = $client->getChangeLogs()->get;

Get changelogs

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanChangelog >>.

=cut

sub _build_getChangeLogs_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/changelog' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getChangeLogs( $self, %options ) {
    my $tx = $self->_build_getChangeLogs_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanChangelog->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getChangeLogsByIds >>

  my $res = $client->getChangeLogsByIds()->get;

Get changelogs by IDs

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


=head3 Options

=over 4

=item C<< changelogIds >>

The list of changelog IDs.

=back

Returns a L<< JIRA::API::PageOfChangelogs >>.

=cut

sub _build_getChangeLogsByIds_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/changelog/list' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueChangelogIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getChangeLogsByIds( $self, %options ) {
    my $tx = $self->_build_getChangeLogsByIds_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageOfChangelogs->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getComments >>

  my $res = $client->getComments()->get;

Get comments

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< orderBy >>

L<Order|#ordering> the results by a field. Accepts I<created> to sort comments by their created date.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about comments in the response. This parameter accepts C<renderedBody>, which returns the comment body rendered in HTML.

=back


Returns a L<< JIRA::API::PageOfComments >>.

=cut

sub _build_getComments_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/comment' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getComments( $self, %options ) {
    my $tx = $self->_build_getComments_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageOfComments->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `orderBy` is set to a value other than *created*.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addComment >>

  my $res = $client->addComment()->get;

Add comment

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about comments in the response. This parameter accepts C<renderedBody>, which returns the comment body rendered in HTML.

=back


=head3 Options

=over 4

=item C<< author >>

The ID of the user who created the comment.

=item C<< body >>

The comment text in L<Atlassian Document Format|https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/>.

=item C<< created >>

The date and time at which the comment was created.

=item C<< id >>

The ID of the comment.

=item C<< jsdAuthorCanSeeRequest >>

Whether the comment was added from an email sent by a person who is not part of the issue. See L<Allow external emails to be added as comments on issues|https://support.atlassian.com/jira-service-management-cloud/docs/allow-external-emails-to-be-added-as-comments-on-issues/>for information on setting up this feature.

=item C<< jsdPublic >>

Whether the comment is visible in Jira Service Desk. Defaults to true when comments are created in the Jira Cloud Platform. This includes when the site doesn't use Jira Service Desk or the project isn't a Jira Service Desk project and, therefore, there is no Jira Service Desk for the issue to be visible on. To create a comment with its visibility in Jira Service Desk set to false, use the Jira Service Desk REST API L<Create request comment|https://developer.atlassian.com/cloud/jira/service-desk/rest/#api-rest-servicedeskapi-request-issueIdOrKey-comment-post> operation.

=item C<< properties >>

A list of comment properties. Optional on create and update.

=item C<< renderedBody >>

The rendered version of the comment.

=item C<< self >>

The URL of the comment.

=item C<< updateAuthor >>

The ID of the user who updated the comment last.

=item C<< updated >>

The date and time at which the comment was updated last.

=item C<< visibility >>

The group or role to which this comment is visible. Optional on create and update.

=back

Returns a L<< JIRA::API::Comment >>.

=cut

sub _build_addComment_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/comment' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::Comment->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addComment( $self, %options ) {
    my $tx = $self->_build_addComment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Comment->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteComment >>

  my $res = $client->deleteComment()->get;

Delete comment

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< id >>

The ID of the comment.

=back



=cut

sub _build_deleteComment_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/comment/{id}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteComment( $self, %options ) {
    my $tx = $self->_build_deleteComment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the user does not have permission to delete the comment.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or comment is not found or the user does not have permission to view the issue or comment.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 405 ) {
            # Returned if an anonymous call is made to the operation.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getComment >>

  my $res = $client->getComment()->get;

Get comment

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< id >>

The ID of the comment.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about comments in the response. This parameter accepts C<renderedBody>, which returns the comment body rendered in HTML.

=back


Returns a L<< JIRA::API::Comment >>.

=cut

sub _build_getComment_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/comment/{id}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getComment( $self, %options ) {
    my $tx = $self->_build_getComment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Comment->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or comment is not found or the user does not have permission to view the issue or comment.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateComment >>

  my $res = $client->updateComment()->get;

Update comment

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< id >>

The ID of the comment.

=item B<< notifyUsers >>

Whether users are notified when a comment is updated.

=item B<< overrideEditableFlag >>

Whether screen security is overridden to enable uneditable fields to be edited. Available to Connect app users with the I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> and Forge apps acting on behalf of users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about comments in the response. This parameter accepts C<renderedBody>, which returns the comment body rendered in HTML.

=back


=head3 Options

=over 4

=item C<< author >>

The ID of the user who created the comment.

=item C<< body >>

The comment text in L<Atlassian Document Format|https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/>.

=item C<< created >>

The date and time at which the comment was created.

=item C<< id >>

The ID of the comment.

=item C<< jsdAuthorCanSeeRequest >>

Whether the comment was added from an email sent by a person who is not part of the issue. See L<Allow external emails to be added as comments on issues|https://support.atlassian.com/jira-service-management-cloud/docs/allow-external-emails-to-be-added-as-comments-on-issues/>for information on setting up this feature.

=item C<< jsdPublic >>

Whether the comment is visible in Jira Service Desk. Defaults to true when comments are created in the Jira Cloud Platform. This includes when the site doesn't use Jira Service Desk or the project isn't a Jira Service Desk project and, therefore, there is no Jira Service Desk for the issue to be visible on. To create a comment with its visibility in Jira Service Desk set to false, use the Jira Service Desk REST API L<Create request comment|https://developer.atlassian.com/cloud/jira/service-desk/rest/#api-rest-servicedeskapi-request-issueIdOrKey-comment-post> operation.

=item C<< properties >>

A list of comment properties. Optional on create and update.

=item C<< renderedBody >>

The rendered version of the comment.

=item C<< self >>

The URL of the comment.

=item C<< updateAuthor >>

The ID of the user who updated the comment last.

=item C<< updated >>

The date and time at which the comment was updated last.

=item C<< visibility >>

The group or role to which this comment is visible. Optional on create and update.

=back

Returns a L<< JIRA::API::Comment >>.

=cut

sub _build_updateComment_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/comment/{id}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'notifyUsers' => delete $options{'notifyUsers'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::Comment->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateComment( $self, %options ) {
    my $tx = $self->_build_updateComment_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Comment->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the user does not have permission to edit the comment or the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or comment is not found or the user does not have permission to view the issue or comment.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getEditIssueMeta >>

  my $res = $client->getEditIssueMeta()->get;

Get edit issue metadata

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< overrideScreenSecurity >>

Whether hidden fields are returned. Available to Connect app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> and Forge apps acting on behalf of users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=item B<< overrideEditableFlag >>

Whether non-editable fields are returned. Available to Connect app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> and Forge apps acting on behalf of users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.

=back


Returns a L<< JIRA::API::IssueUpdateMetadata >>.

=cut

sub _build_getEditIssueMeta_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/editmeta' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'overrideScreenSecurity' => delete $options{'overrideScreenSecurity'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getEditIssueMeta( $self, %options ) {
    my $tx = $self->_build_getEditIssueMeta_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueUpdateMetadata->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user uses an override parameter but doesn't have permission to do so.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< notify >>

  my $res = $client->notify()->get;

Send notification for issue

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

ID or key of the issue that the notification is sent for.

=back


=head3 Options

=over 4

=item C<< htmlBody >>

The HTML body of the email notification for the issue.

=item C<< restrict >>

Restricts the notifications to users with the specified permissions.

=item C<< subject >>

The subject of the email notification for the issue. If this is not specified, then the subject is set to the issue key and summary.

=item C<< textBody >>

The plain text body of the email notification for the issue.

=item C<< to >>

The recipients of the email notification for the issue.

=back

Returns a L<<  >>.

=cut

sub _build_notify_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/notify' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::Notification->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub notify( $self, %options ) {
    my $tx = $self->_build_notify_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the email is queued for sending.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the recipient is the same as the calling user. * the recipient is invalid. For example, the recipient is set to the assignee, but the issue is unassigned. * the request is invalid. For example, required fields are missing or have invalid values.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if: * outgoing emails are disabled. * no SMTP server is configured.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssuePropertyKeys >>

  my $res = $client->getIssuePropertyKeys()->get;

Get issue property keys

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The key or ID of the issue.

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getIssuePropertyKeys_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/properties' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssuePropertyKeys( $self, %options ) {
    my $tx = $self->_build_getIssuePropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permissions to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueProperty >>

  my $res = $client->deleteIssueProperty()->get;

Delete issue property

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The key or ID of the issue.

=item B<< propertyKey >>

The key of the property.

=back



=cut

sub _build_deleteIssueProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteIssueProperty( $self, %options ) {
    my $tx = $self->_build_deleteIssueProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or property is not found, or the user does not have permission to edit the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueProperty >>

  my $res = $client->getIssueProperty()->get;

Get issue property

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The key or ID of the issue.

=item B<< propertyKey >>

The key of the property.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getIssueProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueProperty( $self, %options ) {
    my $tx = $self->_build_getIssueProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or property is not found or the user does not have permission to see the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setIssueProperty >>

  my $res = $client->setIssueProperty()->get;

Set issue property

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< propertyKey >>

The key of the issue property. The maximum length is 255 characters.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setIssueProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setIssueProperty( $self, %options ) {
    my $tx = $self->_build_setIssueProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the issue property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the issue property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to edit the issue.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteRemoteIssueLinkByGlobalId >>

  my $res = $client->deleteRemoteIssueLinkByGlobalId()->get;

Delete remote issue link by global ID

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< globalId >>

The global ID of a remote issue link.

=back



=cut

sub _build_deleteRemoteIssueLinkByGlobalId_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'globalId'"
        unless exists $options{ 'globalId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/remotelink' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'globalId' => delete $options{'globalId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteRemoteIssueLinkByGlobalId( $self, %options ) {
    my $tx = $self->_build_deleteRemoteIssueLinkByGlobalId_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if a global ID isn't provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to link issues.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or remote issue link is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getRemoteIssueLinks >>

  my $res = $client->getRemoteIssueLinks()->get;

Get remote issue links

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< globalId >>

The global ID of the remote issue link.

=back


Returns a L<< JIRA::API::RemoteIssueLink >>.

=cut

sub _build_getRemoteIssueLinks_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/remotelink' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'globalId' => delete $options{'globalId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getRemoteIssueLinks( $self, %options ) {
    my $tx = $self->_build_getRemoteIssueLinks_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::RemoteIssueLink->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if issue linking is disabled.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or remote issue link is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createOrUpdateRemoteIssueLink >>

  my $res = $client->createOrUpdateRemoteIssueLink()->get;

Create or update remote issue link

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


=head3 Options

=over 4

=item C<< application >>

Details of the remote application the linked item is in. For example, trello.

=item C<< globalId >>

An identifier for the remote item in the remote system. For example, the global ID for a remote item in Confluence would consist of the app ID and page ID, like this: C<appId=456&pageId=123>.

Setting this field enables the remote issue link details to be updated or deleted using remote system and item details as the record identifier, rather than using the record's Jira ID.

The maximum length is 255 characters.

=item C<< object >>

Details of the item linked to.

=item C<< relationship >>

Description of the relationship between the issue and the linked item. If not set, the relationship description "links to" is used in Jira.

=back

Returns a L<< JIRA::API::RemoteIssueLinkIdentifies >>.
Returns a L<< JIRA::API::RemoteIssueLinkIdentifies >>.

=cut

sub _build_createOrUpdateRemoteIssueLink_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/remotelink' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::RemoteIssueLinkRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createOrUpdateRemoteIssueLink( $self, %options ) {
    my $tx = $self->_build_createOrUpdateRemoteIssueLink_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the remote issue link is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::RemoteIssueLinkIdentifies->new($payload),

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the remote issue link is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::RemoteIssueLinkIdentifies->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to link issues.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteRemoteIssueLinkById >>

  my $res = $client->deleteRemoteIssueLinkById()->get;

Delete remote issue link by ID

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< linkId >>

The ID of a remote issue link.

=back



=cut

sub _build_deleteRemoteIssueLinkById_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'linkId'"
        unless exists $options{ 'linkId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/remotelink/{linkId}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'linkId' => delete $options{'linkId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteRemoteIssueLinkById( $self, %options ) {
    my $tx = $self->_build_deleteRemoteIssueLinkById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the link ID is invalid or the remote issue link does not belong to the issue.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to link issues.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or remote issue link is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getRemoteIssueLinkById >>

  my $res = $client->getRemoteIssueLinkById()->get;

Get remote issue link by ID

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< linkId >>

The ID of the remote issue link.

=back


Returns a L<< JIRA::API::RemoteIssueLink >>.

=cut

sub _build_getRemoteIssueLinkById_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'linkId'"
        unless exists $options{ 'linkId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/remotelink/{linkId}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'linkId' => delete $options{'linkId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getRemoteIssueLinkById( $self, %options ) {
    my $tx = $self->_build_getRemoteIssueLinkById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::RemoteIssueLink->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the link ID is invalid or the remote issue link does not belong to the issue.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if issue linking is disabled.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or remote issue link is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateRemoteIssueLink >>

  my $res = $client->updateRemoteIssueLink()->get;

Update remote issue link by ID

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< linkId >>

The ID of the remote issue link.

=back


=head3 Options

=over 4

=item C<< application >>

Details of the remote application the linked item is in. For example, trello.

=item C<< globalId >>

An identifier for the remote item in the remote system. For example, the global ID for a remote item in Confluence would consist of the app ID and page ID, like this: C<appId=456&pageId=123>.

Setting this field enables the remote issue link details to be updated or deleted using remote system and item details as the record identifier, rather than using the record's Jira ID.

The maximum length is 255 characters.

=item C<< object >>

Details of the item linked to.

=item C<< relationship >>

Description of the relationship between the issue and the linked item. If not set, the relationship description "links to" is used in Jira.

=back

Returns a L<<  >>.

=cut

sub _build_updateRemoteIssueLink_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'linkId'"
        unless exists $options{ 'linkId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/remotelink/{linkId}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'linkId' => delete $options{'linkId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::RemoteIssueLinkRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateRemoteIssueLink( $self, %options ) {
    my $tx = $self->_build_updateRemoteIssueLink_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the link ID is invalid. * the remote issue link does not belong to the issue. * the request body is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to link issues.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or remote issue link is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getTransitions >>

  my $res = $client->getTransitions()->get;

Get transitions

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about transitions in the response. This parameter accepts C<transitions.fields>, which returns information about the fields in the transition screen for each transition. Fields hidden from the screen are not returned. Use this information to populate the C<fields> and C<update> fields in L<Transition issue|#api-rest-api-3-issue-issueIdOrKey-transitions-post>.

=item B<< transitionId >>

The ID of the transition.

=item B<< skipRemoteOnlyCondition >>

Whether transitions with the condition I<Hide From User Condition> are included in the response.

=item B<< includeUnavailableTransitions >>

Whether details of transitions that fail a condition are included in the response

=item B<< sortByOpsBarAndStatus >>

Whether the transitions are sorted by ops-bar sequence value first then category order (Todo, In Progress, Done) or only by ops-bar sequence value.

=back


Returns a L<< JIRA::API::Transitions >>.

=cut

sub _build_getTransitions_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/transitions' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'transitionId' => delete $options{'transitionId'},
        maybe 'skipRemoteOnlyCondition' => delete $options{'skipRemoteOnlyCondition'},
        maybe 'includeUnavailableTransitions' => delete $options{'includeUnavailableTransitions'},
        maybe 'sortByOpsBarAndStatus' => delete $options{'sortByOpsBarAndStatus'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getTransitions( $self, %options ) {
    my $tx = $self->_build_getTransitions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Transitions->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< doTransition >>

  my $res = $client->doTransition()->get;

Transition issue

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


=head3 Options

=over 4

=item C<< fields >>

List of issue screen fields to update, specifying the sub-field to update and its value for each field. This field provides a straightforward option when setting a sub-field. When multiple sub-fields or other operations are required, use C<update>. Fields included in here cannot be included in C<update>.

=item C<< historyMetadata >>

Additional issue history details.

=item C<< properties >>

Details of issue properties to be add or update.

=item C<< transition >>

Details of a transition. Required when performing a transition, optional when creating or editing an issue.

=item C<< update >>

A Map containing the field field name and a list of operations to perform on the issue screen field. Note that fields included in here cannot be included in C<fields>.

=back

Returns a L<<  >>.

=cut

sub _build_doTransition_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/transitions' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub doTransition( $self, %options ) {
    my $tx = $self->_build_doTransition_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * no transition is specified. * the user does not have permission to transition the issue. * a field that isn't included on the transition screen is defined in `fields` or `update`. * a field is specified in both `fields` and `update`. * the request is invalid for any other reason.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeVote >>

  my $res = $client->removeVote()->get;

Delete vote

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back



=cut

sub _build_removeVote_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/votes' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeVote( $self, %options ) {
    my $tx = $self->_build_removeVote_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * voting is disabled. * the user has not voted on the issue. * the issue is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getVotes >>

  my $res = $client->getVotes()->get;

Get votes

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


Returns a L<< JIRA::API::Votes >>.

=cut

sub _build_getVotes_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/votes' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getVotes( $self, %options ) {
    my $tx = $self->_build_getVotes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Votes->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * voting is disabled. * the user does not have permission to view the issue. * the issue is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addVote >>

  my $res = $client->addVote()->get;

Add vote

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


Returns a L<<  >>.

=cut

sub _build_addVote_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/votes' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub addVote( $self, %options ) {
    my $tx = $self->_build_addVote_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * voting is disabled. * the issue is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeWatcher >>

  my $res = $client->removeWatcher()->get;

Delete watcher

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>. Required.

=back



=cut

sub _build_removeWatcher_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/watchers' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'username' => delete $options{'username'},
        maybe 'accountId' => delete $options{'accountId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeWatcher( $self, %options ) {
    my $tx = $self->_build_removeWatcher_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if `accountId` is not supplied.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the permission to manage the watcher list.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or the user is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueWatchers >>

  my $res = $client->getIssueWatchers()->get;

Get issue watchers

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


Returns a L<< JIRA::API::Watchers >>.

=cut

sub _build_getIssueWatchers_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/watchers' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueWatchers( $self, %options ) {
    my $tx = $self->_build_getIssueWatchers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Watchers->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addWatcher >>

  my $res = $client->addWatcher()->get;

Add watcher

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=back


Returns a L<<  >>.

=cut

sub _build_addWatcher_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/watchers' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $body = delete $options{ body } // '';
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addWatcher( $self, %options ) {
    my $tx = $self->_build_addWatcher_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the permission to manage the watcher list.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or the user is not found or the user does not have permission to view the issue.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueWorklog >>

  my $res = $client->getIssueWorklog()->get;

Get issue worklogs

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< startedAfter >>

The worklog start date and time, as a UNIX timestamp in milliseconds, after which worklogs are returned.

=item B<< startedBefore >>

The worklog start date and time, as a UNIX timestamp in milliseconds, before which worklogs are returned.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about worklogs in the response. This parameter acceptsC<properties>, which returns worklog properties.

=back


Returns a L<< JIRA::API::PageOfWorklogs >>.

=cut

sub _build_getIssueWorklog_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'startedAfter' => delete $options{'startedAfter'},
        maybe 'startedBefore' => delete $options{'startedBefore'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueWorklog( $self, %options ) {
    my $tx = $self->_build_getIssueWorklog_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageOfWorklogs->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue is not found or the user does not have permission to view the issue. * `startAt` or `maxResults` has non-numeric values. * time tracking is disabled.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addWorklog >>

  my $res = $client->addWorklog()->get;

Add worklog

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key the issue.

=item B<< notifyUsers >>

Whether users watching the issue are notified by email.

=item B<< adjustEstimate >>

Defines how to update the issue's time estimate, the options are:

=over

=item *

C<new> Sets the estimate to a specific value, defined in C<newEstimate>.


=item *

C<leave> Leaves the estimate unchanged.


=item *

C<manual> Reduces the estimate by amount specified in C<reduceBy>.


=item *

C<auto> Reduces the estimate by the value of C<timeSpent> in the worklog.


=back

=item B<< newEstimate >>

The value to set as the issue's remaining time estimate, as days (#d), hours (#h), or minutes (#m or #). For example, I<2d>. Required when C<adjustEstimate> is C<new>.

=item B<< reduceBy >>

The amount to reduce the issue's remaining estimate by, as days (#d), hours (#h), or minutes (#m). For example, I<2d>. Required when C<adjustEstimate> is C<manual>.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about work logs in the response. This parameter accepts C<properties>, which returns worklog properties.

=item B<< overrideEditableFlag >>

Whether the worklog entry should be added to the issue even if the issue is not editable, because jira.issue.editable set to false or missing. For example, the issue is closed. Connect and Forge app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> can use this flag.

=back


=head3 Options

=over 4

=item C<< author >>

Details of the user who created the worklog.

=item C<< comment >>

A comment about the worklog in L<Atlassian Document Format|https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/>. Optional when creating or updating a worklog.

=item C<< created >>

The datetime on which the worklog was created.

=item C<< id >>

The ID of the worklog record.

=item C<< issueId >>

The ID of the issue this worklog is for.

=item C<< properties >>

Details of properties for the worklog. Optional when creating or updating a worklog.

=item C<< self >>

The URL of the worklog item.

=item C<< started >>

The datetime on which the worklog effort was started. Required when creating a worklog. Optional when updating a worklog.

=item C<< timeSpent >>

The time spent working on the issue as days (#d), hours (#h), or minutes (#m or #). Required when creating a worklog if C<timeSpentSeconds> isn't provided. Optional when updating a worklog. Cannot be provided if C<timeSpentSecond> is provided.

=item C<< timeSpentSeconds >>

The time in seconds spent working on the issue. Required when creating a worklog if C<timeSpent> isn't provided. Optional when updating a worklog. Cannot be provided if C<timeSpent> is provided.

=item C<< updateAuthor >>

Details of the user who last updated the worklog.

=item C<< updated >>

The datetime on which the worklog was last updated.

=item C<< visibility >>

Details about any restrictions in the visibility of the worklog. Optional when creating or updating a worklog.

=back

Returns a L<< JIRA::API::Worklog >>.

=cut

sub _build_addWorklog_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'notifyUsers' => delete $options{'notifyUsers'},
        maybe 'adjustEstimate' => delete $options{'adjustEstimate'},
        maybe 'newEstimate' => delete $options{'newEstimate'},
        maybe 'reduceBy' => delete $options{'reduceBy'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
    );

    my $request = JIRA::API::Worklog->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addWorklog( $self, %options ) {
    my $tx = $self->_build_addWorklog_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Worklog->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `adjustEstimate` is set to `new` but `newEstimate` is not provided or is invalid. * `adjustEstimate` is set to `manual` but `reduceBy` is not provided or is invalid. * the user does not have permission to add the worklog. * the request JSON is malformed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorklog >>

  my $res = $client->deleteWorklog()->get;

Delete worklog

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< id >>

The ID of the worklog.

=item B<< notifyUsers >>

Whether users watching the issue are notified by email.

=item B<< adjustEstimate >>

Defines how to update the issue's time estimate, the options are:

=over

=item *

C<new> Sets the estimate to a specific value, defined in C<newEstimate>.


=item *

C<leave> Leaves the estimate unchanged.


=item *

C<manual> Increases the estimate by amount specified in C<increaseBy>.


=item *

C<auto> Reduces the estimate by the value of C<timeSpent> in the worklog.


=back

=item B<< newEstimate >>

The value to set as the issue's remaining time estimate, as days (#d), hours (#h), or minutes (#m or #). For example, I<2d>. Required when C<adjustEstimate> is C<new>.

=item B<< increaseBy >>

The amount to increase the issue's remaining estimate by, as days (#d), hours (#h), or minutes (#m or #). For example, I<2d>. Required when C<adjustEstimate> is C<manual>.

=item B<< overrideEditableFlag >>

Whether the work log entry should be added to the issue even if the issue is not editable, because jira.issue.editable set to false or missing. For example, the issue is closed. Connect and Forge app users with admin permission can use this flag.

=back



=cut

sub _build_deleteWorklog_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{id}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'notifyUsers' => delete $options{'notifyUsers'},
        maybe 'adjustEstimate' => delete $options{'adjustEstimate'},
        maybe 'newEstimate' => delete $options{'newEstimate'},
        maybe 'increaseBy' => delete $options{'increaseBy'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteWorklog( $self, %options ) {
    my $tx = $self->_build_deleteWorklog_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if: * `adjustEstimate` is set to `new` but `newEstimate` is not provided or is invalid. * `adjustEstimate` is set to `manual` but `reduceBy` is not provided or is invalid. * the user does not have permission to delete the worklog.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue is not found or user does not have permission to view the issue. * the worklog is not found or the user does not have permission to view it. * time tracking is disabled.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorklog >>

  my $res = $client->getWorklog()->get;

Get worklog

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< id >>

The ID of the worklog.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about work logs in the response. This parameter accepts

C<properties>, which returns worklog properties.

=back


Returns a L<< JIRA::API::Worklog >>.

=cut

sub _build_getWorklog_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{id}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorklog( $self, %options ) {
    my $tx = $self->_build_getWorklog_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Worklog->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue is not found or the user does not have permission to view it. * the worklog is not found or the user does not have permission to view it. * time tracking is disabled. .
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateWorklog >>

  my $res = $client->updateWorklog()->get;

Update worklog

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key the issue.

=item B<< id >>

The ID of the worklog.

=item B<< notifyUsers >>

Whether users watching the issue are notified by email.

=item B<< adjustEstimate >>

Defines how to update the issue's time estimate, the options are:

=over

=item *

C<new> Sets the estimate to a specific value, defined in C<newEstimate>.


=item *

C<leave> Leaves the estimate unchanged.


=item *

C<auto> Updates the estimate by the difference between the original and updated value of C<timeSpent> or C<timeSpentSeconds>.


=back

=item B<< newEstimate >>

The value to set as the issue's remaining time estimate, as days (#d), hours (#h), or minutes (#m or #). For example, I<2d>. Required when C<adjustEstimate> is C<new>.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about worklogs in the response. This parameter accepts C<properties>, which returns worklog properties.

=item B<< overrideEditableFlag >>

Whether the worklog should be added to the issue even if the issue is not editable. For example, because the issue is closed. Connect and Forge app users with I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg> can use this flag.

=back


=head3 Options

=over 4

=item C<< author >>

Details of the user who created the worklog.

=item C<< comment >>

A comment about the worklog in L<Atlassian Document Format|https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/>. Optional when creating or updating a worklog.

=item C<< created >>

The datetime on which the worklog was created.

=item C<< id >>

The ID of the worklog record.

=item C<< issueId >>

The ID of the issue this worklog is for.

=item C<< properties >>

Details of properties for the worklog. Optional when creating or updating a worklog.

=item C<< self >>

The URL of the worklog item.

=item C<< started >>

The datetime on which the worklog effort was started. Required when creating a worklog. Optional when updating a worklog.

=item C<< timeSpent >>

The time spent working on the issue as days (#d), hours (#h), or minutes (#m or #). Required when creating a worklog if C<timeSpentSeconds> isn't provided. Optional when updating a worklog. Cannot be provided if C<timeSpentSecond> is provided.

=item C<< timeSpentSeconds >>

The time in seconds spent working on the issue. Required when creating a worklog if C<timeSpent> isn't provided. Optional when updating a worklog. Cannot be provided if C<timeSpent> is provided.

=item C<< updateAuthor >>

Details of the user who last updated the worklog.

=item C<< updated >>

The datetime on which the worklog was last updated.

=item C<< visibility >>

Details about any restrictions in the visibility of the worklog. Optional when creating or updating a worklog.

=back

Returns a L<< JIRA::API::Worklog >>.

=cut

sub _build_updateWorklog_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{id}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'notifyUsers' => delete $options{'notifyUsers'},
        maybe 'adjustEstimate' => delete $options{'adjustEstimate'},
        maybe 'newEstimate' => delete $options{'newEstimate'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'overrideEditableFlag' => delete $options{'overrideEditableFlag'},
    );

    my $request = JIRA::API::Worklog->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateWorklog( $self, %options ) {
    my $tx = $self->_build_updateWorklog_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Worklog->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `adjustEstimate` is set to `new` but `newEstimate` is not provided or is invalid. * the user does not have permission to update the worklog. * the request JSON is malformed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue is not found or user does not have permission to view the issue. * the worklog is not found or the user does not have permission to view it. * time tracking is disabled.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorklogPropertyKeys >>

  my $res = $client->getWorklogPropertyKeys()->get;

Get worklog property keys

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< worklogId >>

The ID of the worklog.

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getWorklogPropertyKeys_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'worklogId'"
        unless exists $options{ 'worklogId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{worklogId}/properties' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'worklogId' => delete $options{'worklogId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorklogPropertyKeys( $self, %options ) {
    my $tx = $self->_build_getWorklogPropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the worklog ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue or worklog is not found. * the user does not have permission to view the issue or worklog.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorklogProperty >>

  my $res = $client->deleteWorklogProperty()->get;

Delete worklog property

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< worklogId >>

The ID of the worklog.

=item B<< propertyKey >>

The key of the property.

=back



=cut

sub _build_deleteWorklogProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'worklogId'"
        unless exists $options{ 'worklogId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{worklogId}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'worklogId' => delete $options{'worklogId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteWorklogProperty( $self, %options ) {
    my $tx = $self->_build_deleteWorklogProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the worklog property is removed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the worklog key or id is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to edit the worklog.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue, worklog, or property is not found. * the user does not have permission to view the issue or worklog.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorklogProperty >>

  my $res = $client->getWorklogProperty()->get;

Get worklog property

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< worklogId >>

The ID of the worklog.

=item B<< propertyKey >>

The key of the property.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getWorklogProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'worklogId'"
        unless exists $options{ 'worklogId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{worklogId}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'worklogId' => delete $options{'worklogId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorklogProperty( $self, %options ) {
    my $tx = $self->_build_getWorklogProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the worklog ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue, worklog, or property is not found. * the user does not have permission to view the issue or worklog.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setWorklogProperty >>

  my $res = $client->setWorklogProperty()->get;

Set worklog property

=head3 Parameters

=over 4

=item B<< issueIdOrKey >>

The ID or key of the issue.

=item B<< worklogId >>

The ID of the worklog.

=item B<< propertyKey >>

The key of the issue property. The maximum length is 255 characters.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setWorklogProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueIdOrKey'"
        unless exists $options{ 'issueIdOrKey' };
    croak "Missing required parameter 'worklogId'"
        unless exists $options{ 'worklogId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issue/{issueIdOrKey}/worklog/{worklogId}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueIdOrKey' => delete $options{'issueIdOrKey'},
              'worklogId' => delete $options{'worklogId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setWorklogProperty( $self, %options ) {
    my $tx = $self->_build_setWorklogProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the worklog property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the worklog property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the worklog ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to edit the worklog.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue or worklog is not found. * the user does not have permission to view the issue or worklog.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< linkIssues >>

  my $res = $client->linkIssues()->get;

Create issue link

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< comment >>

A comment.

=item C<< inwardIssue >>

The ID or key of a linked issue.

=item C<< outwardIssue >>

The ID or key of a linked issue.

=item C<< type >>

This object is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it defines and reports on the type of link between the issues. Find a list of issue link types with L<Get issue link types|#api-rest-api-3-issueLinkType-get>.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it defines and reports on issue link types.


=back

=back

Returns a L<<  >>.

=cut

sub _build_linkIssues_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issueLink';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::LinkIssueRequestJsonBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub linkIssues( $self, %options ) {
    my $tx = $self->_build_linkIssues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the comment is not created. The response contains an error message indicating why the comment wasn't created. The issue link is also not created.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the user cannot view one or both of the issues. For example, the user doesn't have *Browse project* project permission for a project containing one of the issues. * the user does not have *link issues* project permission. * either of the link issues are not found. * the issue link type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueLink >>

  my $res = $client->deleteIssueLink()->get;

Delete issue link

=head3 Parameters

=over 4

=item B<< linkId >>

The ID of the issue link.

=back



=cut

sub _build_deleteIssueLink_request( $self, %options ) {
    croak "Missing required parameter 'linkId'"
        unless exists $options{ 'linkId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issueLink/{linkId}' );
    my $path = $template->process(
              'linkId' => delete $options{'linkId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteIssueLink( $self, %options ) {
    my $tx = $self->_build_deleteIssueLink_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the issue link ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the issue link is not found. * the user doesn't have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueLink >>

  my $res = $client->getIssueLink()->get;

Get issue link

=head3 Parameters

=over 4

=item B<< linkId >>

The ID of the issue link.

=back


Returns a L<< JIRA::API::IssueLink >>.

=cut

sub _build_getIssueLink_request( $self, %options ) {
    croak "Missing required parameter 'linkId'"
        unless exists $options{ 'linkId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issueLink/{linkId}' );
    my $path = $template->process(
              'linkId' => delete $options{'linkId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueLink( $self, %options ) {
    my $tx = $self->_build_getIssueLink_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueLink->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the issue link ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the issue link is not found. * the user doesn't have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueLinkTypes >>

  my $res = $client->getIssueLinkTypes()->get;

Get issue link types

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::IssueLinkTypes >>.

=cut

sub _build_getIssueLinkTypes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issueLinkType';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueLinkTypes( $self, %options ) {
    my $tx = $self->_build_getIssueLinkTypes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueLinkTypes->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if issue linking is disabled.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssueLinkType >>

  my $res = $client->createIssueLinkType()->get;

Create issue link type

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the issue link type and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is the type of issue link. Required on create when C<name> isn't provided. Otherwise, read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is read only.


=back

=item C<< inward >>

The description of the issue link type inward link and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is required on create and optional on update. Otherwise, read only.


=back

=item C<< name >>

The name of the issue link type and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is the type of issue link. Required on create when C<id> isn't provided. Otherwise, read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is required on create and optional on update. Otherwise, read only.


=back

=item C<< outward >>

The description of the issue link type outward link and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is required on create and optional on update. Otherwise, read only.


=back

=item C<< self >>

The URL of the issue link type. Read only.

=back

Returns a L<< JIRA::API::IssueLinkType >>.

=cut

sub _build_createIssueLinkType_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issueLinkType';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueLinkType->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssueLinkType( $self, %options ) {
    my $tx = $self->_build_createIssueLinkType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueLinkType->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the issue link type name is in use. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueLinkType >>

  my $res = $client->deleteIssueLinkType()->get;

Delete issue link type

=head3 Parameters

=over 4

=item B<< issueLinkTypeId >>

The ID of the issue link type.

=back



=cut

sub _build_deleteIssueLinkType_request( $self, %options ) {
    croak "Missing required parameter 'issueLinkTypeId'"
        unless exists $options{ 'issueLinkTypeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issueLinkType/{issueLinkTypeId}' );
    my $path = $template->process(
              'issueLinkTypeId' => delete $options{'issueLinkTypeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteIssueLinkType( $self, %options ) {
    my $tx = $self->_build_deleteIssueLinkType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the issue link type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the issue link type is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueLinkType >>

  my $res = $client->getIssueLinkType()->get;

Get issue link type

=head3 Parameters

=over 4

=item B<< issueLinkTypeId >>

The ID of the issue link type.

=back


Returns a L<< JIRA::API::IssueLinkType >>.

=cut

sub _build_getIssueLinkType_request( $self, %options ) {
    croak "Missing required parameter 'issueLinkTypeId'"
        unless exists $options{ 'issueLinkTypeId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issueLinkType/{issueLinkTypeId}' );
    my $path = $template->process(
              'issueLinkTypeId' => delete $options{'issueLinkTypeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueLinkType( $self, %options ) {
    my $tx = $self->_build_getIssueLinkType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueLinkType->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the issue link type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the issue link type is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateIssueLinkType >>

  my $res = $client->updateIssueLinkType()->get;

Update issue link type

=head3 Parameters

=over 4

=item B<< issueLinkTypeId >>

The ID of the issue link type.

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the issue link type and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is the type of issue link. Required on create when C<name> isn't provided. Otherwise, read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is read only.


=back

=item C<< inward >>

The description of the issue link type inward link and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is required on create and optional on update. Otherwise, read only.


=back

=item C<< name >>

The name of the issue link type and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is the type of issue link. Required on create when C<id> isn't provided. Otherwise, read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is required on create and optional on update. Otherwise, read only.


=back

=item C<< outward >>

The description of the issue link type outward link and is used as follows:

=over

=item *

In the L< issueLink|#api-rest-api-3-issueLink-post> resource it is read only.


=item *

In the L< issueLinkType|#api-rest-api-3-issueLinkType-post> resource it is required on create and optional on update. Otherwise, read only.


=back

=item C<< self >>

The URL of the issue link type. Read only.

=back

Returns a L<< JIRA::API::IssueLinkType >>.

=cut

sub _build_updateIssueLinkType_request( $self, %options ) {
    croak "Missing required parameter 'issueLinkTypeId'"
        unless exists $options{ 'issueLinkTypeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issueLinkType/{issueLinkTypeId}' );
    my $path = $template->process(
              'issueLinkTypeId' => delete $options{'issueLinkTypeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueLinkType->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateIssueLinkType( $self, %options ) {
    my $tx = $self->_build_updateIssueLinkType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueLinkType->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the issue link type ID or the request body are invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * issue linking is disabled. * the issue link type is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueSecuritySchemes >>

  my $res = $client->getIssueSecuritySchemes()->get;

Get issue security schemes

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::SecuritySchemes >>.

=cut

sub _build_getIssueSecuritySchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issuesecurityschemes';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueSecuritySchemes( $self, %options ) {
    my $tx = $self->_build_getIssueSecuritySchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SecuritySchemes->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to administer issue security schemes.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueSecurityScheme >>

  my $res = $client->getIssueSecurityScheme()->get;

Get issue security scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue security scheme. Use the L<Get issue security schemes|#api-rest-api-3-issuesecurityschemes-get> operation to get a list of issue security scheme IDs.

=back


Returns a L<< JIRA::API::SecurityScheme >>.

=cut

sub _build_getIssueSecurityScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuesecurityschemes/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueSecurityScheme( $self, %options ) {
    my $tx = $self->_build_getIssueSecurityScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SecurityScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the administrator permission and the scheme is not used in any project where the user has administrative permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueSecurityLevelMembers >>

  my $res = $client->getIssueSecurityLevelMembers()->get;

Get issue security level members

=head3 Parameters

=over 4

=item B<< issueSecuritySchemeId >>

The ID of the issue security scheme. Use the L<Get issue security schemes|#api-rest-api-3-issuesecurityschemes-get> operation to get a list of issue security scheme IDs.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< issueSecurityLevelId >>

The list of issue security level IDs. To include multiple issue security levels separate IDs with ampersand: C<issueSecurityLevelId=10000&issueSecurityLevelId=10001>.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


Returns a L<< JIRA::API::PageBeanIssueSecurityLevelMember >>.

=cut

sub _build_getIssueSecurityLevelMembers_request( $self, %options ) {
    croak "Missing required parameter 'issueSecuritySchemeId'"
        unless exists $options{ 'issueSecuritySchemeId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuesecurityschemes/{issueSecuritySchemeId}/members' );
    my $path = $template->process(
              'issueSecuritySchemeId' => delete $options{'issueSecuritySchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'issueSecurityLevelId' => delete $options{'issueSecurityLevelId'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueSecurityLevelMembers( $self, %options ) {
    my $tx = $self->_build_getIssueSecurityLevelMembers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueSecurityLevelMember->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if no issue security level members are found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueAllTypes >>

  my $res = $client->getIssueAllTypes()->get;

Get all issue types for user

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::IssueTypeDetails >>.

=cut

sub _build_getIssueAllTypes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issuetype';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueAllTypes( $self, %options ) {
    my $tx = $self->_build_getIssueAllTypes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::IssueTypeDetails->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssueType >>

  my $res = $client->createIssueType()->get;

Create issue type

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the issue type.

=item C<< hierarchyLevel >>

The hierarchy level of the issue type. Use:

=over

=item *

C<-1> for Subtask.


=item *

C<0> for Base.


=back

Defaults to C<0>.

=item C<< name >>

The unique name for the issue type. The maximum length is 60 characters.

=item C<< type >>

Deprecated. Use C<hierarchyLevel> instead. See the L<deprecation notice|https://community.developer.atlassian.com/t/deprecation-of-the-epic-link-parent-link-and-other-related-fields-in-rest-apis-and-webhooks/54048> for details.

Whether the issue type is C<subtype> or C<standard>. Defaults to C<standard>.

=back

Returns a L<< JIRA::API::IssueTypeDetails >>.

=cut

sub _build_createIssueType_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issuetype';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeCreateBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssueType( $self, %options ) {
    my $tx = $self->_build_createIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid because: * no content is sent. * the issue type name exceeds 60 characters. * a subtask issue type is requested on an instance where subtasks are disabled.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type name is in use.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypesForProject >>

  my $res = $client->getIssueTypesForProject()->get;

Get issue types for project

=head3 Parameters

=over 4

=item B<< projectId >>

The ID of the project.

=item B<< level >>

The level of the issue type to filter by. Use:

=over

=item *

C<-1> for Subtask.


=item *

C<0> for Base.


=item *

C<1> for Epic.


=back

=back


Returns an array of L<< JIRA::API::IssueTypeDetails >>.

=cut

sub _build_getIssueTypesForProject_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $path = '/rest/api/3/issuetype/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'projectId' => delete $options{'projectId'},
        maybe 'level' => delete $options{'level'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypesForProject( $self, %options ) {
    my $tx = $self->_build_getIssueTypesForProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::IssueTypeDetails->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the project is not found. * the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueType >>

  my $res = $client->deleteIssueType()->get;

Delete issue type

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue type.

=item B<< alternativeIssueTypeId >>

The ID of the replacement issue type.

=back



=cut

sub _build_deleteIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'alternativeIssueTypeId' => delete $options{'alternativeIssueTypeId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteIssueType( $self, %options ) {
    my $tx = $self->_build_deleteIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if any issues cannot be updated with the alternative issue type.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue type is in use and an alternative issue type is not specified. * the issue type or alternative issue type is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type is in use and: * also specified as the alternative issue type. * is a *standard* issue type and the alternative issue type is a *subtask*.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueType >>

  my $res = $client->getIssueType()->get;

Get issue type

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue type.

=back


Returns a L<< JIRA::API::IssueTypeDetails >>.

=cut

sub _build_getIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueType( $self, %options ) {
    my $tx = $self->_build_getIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the issue type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue type is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateIssueType >>

  my $res = $client->updateIssueType()->get;

Update issue type

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue type.

=back


=head3 Options

=over 4

=item C<< avatarId >>

The ID of an issue type avatar.

=item C<< description >>

The description of the issue type.

=item C<< name >>

The unique name for the issue type. The maximum length is 60 characters.

=back

Returns a L<< JIRA::API::IssueTypeDetails >>.

=cut

sub _build_updateIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeUpdateBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateIssueType( $self, %options ) {
    my $tx = $self->_build_updateIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid because: * no content is sent. * the issue type name exceeds 60 characters. * the avatar is not associated with this issue type.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type name is in use.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAlternativeIssueTypes >>

  my $res = $client->getAlternativeIssueTypes()->get;

Get alternative issue types

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue type.

=back


Returns an array of L<< JIRA::API::IssueTypeDetails >>.

=cut

sub _build_getAlternativeIssueTypes_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{id}/alternatives' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAlternativeIssueTypes( $self, %options ) {
    my $tx = $self->_build_getAlternativeIssueTypes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::IssueTypeDetails->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue type is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssueTypeAvatar >>

  my $res = $client->createIssueTypeAvatar()->get;

Load issue type avatar

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue type.

=item B<< x >>

The X coordinate of the top-left corner of the crop region.

=item B<< y >>

The Y coordinate of the top-left corner of the crop region.

=item B<< size >>

The length of each side of the crop region.

=back


Returns a L<< JIRA::API::Avatar >>.

=cut

sub _build_createIssueTypeAvatar_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'size'"
        unless exists $options{ 'size' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{id}/avatar2' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'x' => delete $options{'x'},
        maybe 'y' => delete $options{'y'},
              'size' => delete $options{'size'},
    );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => '*/*',
        }
        # XXX Need to fill the body
        # => $body,
    );

    return $tx
}


sub createIssueTypeAvatar( $self, %options ) {
    my $tx = $self->_build_createIssueTypeAvatar_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Avatar->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * an image isn't included in the request. * the image type is unsupported. * the crop parameters extend the crop area beyond the edge of the image. * `cropSize` is missing. * the issue type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypePropertyKeys >>

  my $res = $client->getIssueTypePropertyKeys()->get;

Get issue type property keys

=head3 Parameters

=over 4

=item B<< issueTypeId >>

The ID of the issue type.

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getIssueTypePropertyKeys_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeId'"
        unless exists $options{ 'issueTypeId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{issueTypeId}/properties' );
    my $path = $template->process(
              'issueTypeId' => delete $options{'issueTypeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypePropertyKeys( $self, %options ) {
    my $tx = $self->_build_getIssueTypePropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the issue type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue type is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueTypeProperty >>

  my $res = $client->deleteIssueTypeProperty()->get;

Delete issue type property

=head3 Parameters

=over 4

=item B<< issueTypeId >>

The ID of the issue type.

=item B<< propertyKey >>

The key of the property. Use L<Get issue type property keys|#api-rest-api-3-issuetype-issueTypeId-properties-get> to get a list of all issue type property keys.

=back



=cut

sub _build_deleteIssueTypeProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeId'"
        unless exists $options{ 'issueTypeId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{issueTypeId}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueTypeId' => delete $options{'issueTypeId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteIssueTypeProperty( $self, %options ) {
    my $tx = $self->_build_deleteIssueTypeProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the issue type property is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the issue type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type or property is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeProperty >>

  my $res = $client->getIssueTypeProperty()->get;

Get issue type property

=head3 Parameters

=over 4

=item B<< issueTypeId >>

The ID of the issue type.

=item B<< propertyKey >>

The key of the property. Use L<Get issue type property keys|#api-rest-api-3-issuetype-issueTypeId-properties-get> to get a list of all issue type property keys.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getIssueTypeProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeId'"
        unless exists $options{ 'issueTypeId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{issueTypeId}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueTypeId' => delete $options{'issueTypeId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeProperty( $self, %options ) {
    my $tx = $self->_build_getIssueTypeProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the issue type ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type or property is not found or the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setIssueTypeProperty >>

  my $res = $client->setIssueTypeProperty()->get;

Set issue type property

=head3 Parameters

=over 4

=item B<< issueTypeId >>

The ID of the issue type.

=item B<< propertyKey >>

The key of the issue type property. The maximum length is 255 characters.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setIssueTypeProperty_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeId'"
        unless exists $options{ 'issueTypeId' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetype/{issueTypeId}/properties/{propertyKey}' );
    my $path = $template->process(
              'issueTypeId' => delete $options{'issueTypeId'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setIssueTypeProperty( $self, %options ) {
    my $tx = $self->_build_setIssueTypeProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the issue type property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the issue type property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the issue type ID is invalid. * a property value is not provided. * the property value JSON content is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to modify the issue type.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the issue type is not found. * the user does not have the permission view the issue type.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllIssueTypeSchemes >>

  my $res = $client->getAllIssueTypeSchemes()->get;

Get all issue type schemes

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of issue type schemes IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<name> Sorts by issue type scheme name.


=item *

C<id> Sorts by issue type scheme ID.


=back

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<projects> For each issue type schemes, returns information about the projects the issue type scheme is assigned to.


=item *

C<issueTypes> For each issue type schemes, returns information about the issueTypes the issue type scheme have.


=back

=item B<< queryString >>

String used to perform a case-insensitive partial match with issue type scheme name.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeScheme >>.

=cut

sub _build_getAllIssueTypeSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issuetypescheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'queryString' => delete $options{'queryString'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllIssueTypeSchemes( $self, %options ) {
    my $tx = $self->_build_getAllIssueTypeSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssueTypeScheme >>

  my $res = $client->createIssueTypeScheme()->get;

Create issue type scheme

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< defaultIssueTypeId >>

The ID of the default issue type of the issue type scheme. This ID must be included in C<issueTypeIds>.

=item C<< description >>

The description of the issue type scheme. The maximum length is 4000 characters.

=item C<< issueTypeIds >>

The list of issue types IDs of the issue type scheme. At least one standard issue type ID is required.

=item C<< name >>

The name of the issue type scheme. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::IssueTypeSchemeID >>.

=cut

sub _build_createIssueTypeScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issuetypescheme';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssueTypeScheme( $self, %options ) {
    my $tx = $self->_build_createIssueTypeScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeSchemeID->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if the scheme name is used by another scheme.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeSchemesMapping >>

  my $res = $client->getIssueTypeSchemesMapping()->get;

Get issue type scheme items

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< issueTypeSchemeId >>

The list of issue type scheme IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<issueTypeSchemeId=10000&issueTypeSchemeId=10001>.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeSchemeMapping >>.

=cut

sub _build_getIssueTypeSchemesMapping_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issuetypescheme/mapping';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'issueTypeSchemeId' => delete $options{'issueTypeSchemeId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeSchemesMapping( $self, %options ) {
    my $tx = $self->_build_getIssueTypeSchemesMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeSchemeMapping->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeSchemeForProjects >>

  my $res = $client->getIssueTypeSchemeForProjects()->get;

Get issue type schemes for projects

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< projectId >>

The list of project IDs. To include multiple project IDs, provide an ampersand-separated list. For example, C<projectId=10000&projectId=10001>.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeSchemeProjects >>.

=cut

sub _build_getIssueTypeSchemeForProjects_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $path = '/rest/api/3/issuetypescheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
              'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeSchemeForProjects( $self, %options ) {
    my $tx = $self->_build_getIssueTypeSchemeForProjects_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeSchemeProjects->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignIssueTypeSchemeToProject >>

  my $res = $client->assignIssueTypeSchemeToProject()->get;

Assign issue type scheme to project

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< issueTypeSchemeId >>

The ID of the issue type scheme.

=item C<< projectId >>

The ID of the project.

=back

Returns a L<<  >>.

=cut

sub _build_assignIssueTypeSchemeToProject_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/issuetypescheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeSchemeProjectAssociation->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignIssueTypeSchemeToProject( $self, %options ) {
    my $tx = $self->_build_assignIssueTypeSchemeToProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type scheme or the project is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueTypeScheme >>

  my $res = $client->deleteIssueTypeScheme()->get;

Delete issue type scheme

=head3 Parameters

=over 4

=item B<< issueTypeSchemeId >>

The ID of the issue type scheme.

=back


Returns a L<<  >>.

=cut

sub _build_deleteIssueTypeScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeSchemeId'"
        unless exists $options{ 'issueTypeSchemeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issuetypescheme/{issueTypeSchemeId}' );
    my $path = $template->process(
              'issueTypeSchemeId' => delete $options{'issueTypeSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteIssueTypeScheme( $self, %options ) {
    my $tx = $self->_build_deleteIssueTypeScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the issue type scheme is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is to delete the default issue type scheme.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateIssueTypeScheme >>

  my $res = $client->updateIssueTypeScheme()->get;

Update issue type scheme

=head3 Parameters

=over 4

=item B<< issueTypeSchemeId >>

The ID of the issue type scheme.

=back


=head3 Options

=over 4

=item C<< defaultIssueTypeId >>

The ID of the default issue type of the issue type scheme.

=item C<< description >>

The description of the issue type scheme. The maximum length is 4000 characters.

=item C<< name >>

The name of the issue type scheme. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<<  >>.

=cut

sub _build_updateIssueTypeScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeSchemeId'"
        unless exists $options{ 'issueTypeSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetypescheme/{issueTypeSchemeId}' );
    my $path = $template->process(
              'issueTypeSchemeId' => delete $options{'issueTypeSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeSchemeUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateIssueTypeScheme( $self, %options ) {
    my $tx = $self->_build_updateIssueTypeScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addIssueTypesToIssueTypeScheme >>

  my $res = $client->addIssueTypesToIssueTypeScheme()->get;

Add issue types to issue type scheme

=head3 Parameters

=over 4

=item B<< issueTypeSchemeId >>

The ID of the issue type scheme.

=back


=head3 Options

=over 4

=item C<< issueTypeIds >>

The list of issue type IDs.

=back

Returns a L<<  >>.

=cut

sub _build_addIssueTypesToIssueTypeScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeSchemeId'"
        unless exists $options{ 'issueTypeSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetypescheme/{issueTypeSchemeId}/issuetype' );
    my $path = $template->process(
              'issueTypeSchemeId' => delete $options{'issueTypeSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addIssueTypesToIssueTypeScheme( $self, %options ) {
    my $tx = $self->_build_addIssueTypesToIssueTypeScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type or the issue type scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< reorderIssueTypesInIssueTypeScheme >>

  my $res = $client->reorderIssueTypesInIssueTypeScheme()->get;

Change order of issue types

=head3 Parameters

=over 4

=item B<< issueTypeSchemeId >>

The ID of the issue type scheme.

=back


=head3 Options

=over 4

=item C<< after >>

The ID of the issue type to place the moved issue types after. Required if C<position> isn't provided.

=item C<< issueTypeIds >>

A list of the issue type IDs to move. The order of the issue type IDs in the list is the order they are given after the move.

=item C<< position >>

The position the issue types should be moved to. Required if C<after> isn't provided.

=back

Returns a L<<  >>.

=cut

sub _build_reorderIssueTypesInIssueTypeScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeSchemeId'"
        unless exists $options{ 'issueTypeSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetypescheme/{issueTypeSchemeId}/issuetype/move' );
    my $path = $template->process(
              'issueTypeSchemeId' => delete $options{'issueTypeSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::OrderOfIssueTypes->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub reorderIssueTypesInIssueTypeScheme( $self, %options ) {
    my $tx = $self->_build_reorderIssueTypesInIssueTypeScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeIssueTypeFromIssueTypeScheme >>

  my $res = $client->removeIssueTypeFromIssueTypeScheme()->get;

Remove issue type from issue type scheme

=head3 Parameters

=over 4

=item B<< issueTypeSchemeId >>

The ID of the issue type scheme.

=item B<< issueTypeId >>

The ID of the issue type.

=back


Returns a L<<  >>.

=cut

sub _build_removeIssueTypeFromIssueTypeScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeSchemeId'"
        unless exists $options{ 'issueTypeSchemeId' };
    croak "Missing required parameter 'issueTypeId'"
        unless exists $options{ 'issueTypeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issuetypescheme/{issueTypeSchemeId}/issuetype/{issueTypeId}' );
    my $path = $template->process(
              'issueTypeSchemeId' => delete $options{'issueTypeSchemeId'},
              'issueTypeId' => delete $options{'issueTypeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub removeIssueTypeFromIssueTypeScheme( $self, %options ) {
    my $tx = $self->_build_removeIssueTypeFromIssueTypeScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type scheme is missing or the issue type is not found in the issue type scheme.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeScreenSchemes >>

  my $res = $client->getIssueTypeScreenSchemes()->get;

Get issue type screen schemes

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of issue type screen scheme IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>.

=item B<< queryString >>

String used to perform a case-insensitive partial match with issue type screen scheme name.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<name> Sorts by issue type screen scheme name.


=item *

C<id> Sorts by issue type screen scheme ID.


=back

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts C<projects> that, for each issue type screen schemes, returns information about the projects the issue type screen scheme is assigned to.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeScreenScheme >>.

=cut

sub _build_getIssueTypeScreenSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issuetypescreenscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'queryString' => delete $options{'queryString'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeScreenSchemes( $self, %options ) {
    my $tx = $self->_build_getIssueTypeScreenSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeScreenScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createIssueTypeScreenScheme >>

  my $res = $client->createIssueTypeScreenScheme()->get;

Create issue type screen scheme

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the issue type screen scheme. The maximum length is 255 characters.

=item C<< issueTypeMappings >>

The IDs of the screen schemes for the issue type IDs and I<default>. A I<default> entry is required to create an issue type screen scheme, it defines the mapping for all issue types without a screen scheme.

=item C<< name >>

The name of the issue type screen scheme. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::IssueTypeScreenSchemeId >>.

=cut

sub _build_createIssueTypeScreenScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/issuetypescreenscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeScreenSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createIssueTypeScreenScheme( $self, %options ) {
    my $tx = $self->_build_createIssueTypeScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeScreenSchemeId->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type or screen scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type is a sub-task, but sub-tasks are disabled in Jira settings.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeScreenSchemeMappings >>

  my $res = $client->getIssueTypeScreenSchemeMappings()->get;

Get issue type screen scheme items

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< issueTypeScreenSchemeId >>

The list of issue type screen scheme IDs. To include multiple issue type screen schemes, separate IDs with ampersand: C<issueTypeScreenSchemeId=10000&issueTypeScreenSchemeId=10001>.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeScreenSchemeItem >>.

=cut

sub _build_getIssueTypeScreenSchemeMappings_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/issuetypescreenscheme/mapping';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeScreenSchemeMappings( $self, %options ) {
    my $tx = $self->_build_getIssueTypeScreenSchemeMappings_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeScreenSchemeItem->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueTypeScreenSchemeProjectAssociations >>

  my $res = $client->getIssueTypeScreenSchemeProjectAssociations()->get;

Get issue type screen schemes for projects

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< projectId >>

The list of project IDs. To include multiple projects, separate IDs with ampersand: C<projectId=10000&projectId=10001>.

=back


Returns a L<< JIRA::API::PageBeanIssueTypeScreenSchemesProjects >>.

=cut

sub _build_getIssueTypeScreenSchemeProjectAssociations_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $path = '/rest/api/3/issuetypescreenscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
              'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueTypeScreenSchemeProjectAssociations( $self, %options ) {
    my $tx = $self->_build_getIssueTypeScreenSchemeProjectAssociations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanIssueTypeScreenSchemesProjects->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignIssueTypeScreenSchemeToProject >>

  my $res = $client->assignIssueTypeScreenSchemeToProject()->get;

Assign issue type screen scheme to project

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=item C<< projectId >>

The ID of the project.

=back

Returns a L<<  >>.

=cut

sub _build_assignIssueTypeScreenSchemeToProject_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/issuetypescreenscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeScreenSchemeProjectAssociation->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignIssueTypeScreenSchemeToProject( $self, %options ) {
    my $tx = $self->_build_assignIssueTypeScreenSchemeToProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * project is not found. * issue type screen scheme is not found. * the project is not a classic project.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type screen scheme or the project are missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteIssueTypeScreenScheme >>

  my $res = $client->deleteIssueTypeScreenScheme()->get;

Delete issue type screen scheme

=head3 Parameters

=over 4

=item B<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=back


Returns a L<<  >>.

=cut

sub _build_deleteIssueTypeScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeScreenSchemeId'"
        unless exists $options{ 'issueTypeScreenSchemeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/issuetypescreenscheme/{issueTypeScreenSchemeId}' );
    my $path = $template->process(
              'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteIssueTypeScreenScheme( $self, %options ) {
    my $tx = $self->_build_deleteIssueTypeScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the issue type screen scheme is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type screen scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateIssueTypeScreenScheme >>

  my $res = $client->updateIssueTypeScreenScheme()->get;

Update issue type screen scheme

=head3 Parameters

=over 4

=item B<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the issue type screen scheme. The maximum length is 255 characters.

=item C<< name >>

The name of the issue type screen scheme. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<<  >>.

=cut

sub _build_updateIssueTypeScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeScreenSchemeId'"
        unless exists $options{ 'issueTypeScreenSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetypescreenscheme/{issueTypeScreenSchemeId}' );
    my $path = $template->process(
              'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeScreenSchemeUpdateDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateIssueTypeScreenScheme( $self, %options ) {
    my $tx = $self->_build_updateIssueTypeScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type screen scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< appendMappingsForIssueTypeScreenScheme >>

  my $res = $client->appendMappingsForIssueTypeScreenScheme()->get;

Append mappings to issue type screen scheme

=head3 Parameters

=over 4

=item B<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=back


=head3 Options

=over 4

=item C<< issueTypeMappings >>

The list of issue type to screen scheme mappings. A I<default> entry cannot be specified because a default entry is added when an issue type screen scheme is created.

=back

Returns a L<<  >>.

=cut

sub _build_appendMappingsForIssueTypeScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeScreenSchemeId'"
        unless exists $options{ 'issueTypeScreenSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetypescreenscheme/{issueTypeScreenSchemeId}/mapping' );
    my $path = $template->process(
              'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeScreenSchemeMappingDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub appendMappingsForIssueTypeScreenScheme( $self, %options ) {
    my $tx = $self->_build_appendMappingsForIssueTypeScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type screen scheme, issue type, or screen scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if the issue type is a sub-task, but sub-tasks are disabled in Jira settings.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateDefaultScreenScheme >>

  my $res = $client->updateDefaultScreenScheme()->get;

Update issue type screen scheme default screen scheme

=head3 Parameters

=over 4

=item B<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=back


=head3 Options

=over 4

=item C<< screenSchemeId >>

The ID of the screen scheme.

=back

Returns a L<<  >>.

=cut

sub _build_updateDefaultScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeScreenSchemeId'"
        unless exists $options{ 'issueTypeScreenSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/issuetypescreenscheme/{issueTypeScreenSchemeId}/mapping/default' );
    my $path = $template->process(
              'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateDefaultScreenScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateDefaultScreenScheme( $self, %options ) {
    my $tx = $self->_build_updateDefaultScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type screen scheme or the screen screen is not found, or the screen scheme isn't used in classic projects.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeMappingsFromIssueTypeScreenScheme >>

  my $res = $client->removeMappingsFromIssueTypeScreenScheme()->get;

Remove mappings from issue type screen scheme

=head3 Parameters

=over 4

=item B<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=back


=head3 Options

=over 4

=item C<< issueTypeIds >>

The list of issue type IDs.

=back

Returns a L<<  >>.

=cut

sub _build_removeMappingsFromIssueTypeScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeScreenSchemeId'"
        unless exists $options{ 'issueTypeScreenSchemeId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/issuetypescreenscheme/{issueTypeScreenSchemeId}/mapping/remove' );
    my $path = $template->process(
              'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeIds->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub removeMappingsFromIssueTypeScreenScheme( $self, %options ) {
    my $tx = $self->_build_removeMappingsFromIssueTypeScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the screen scheme mappings are removed from the issue type screen scheme.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue type screen scheme or one or more issue type mappings are not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectsForIssueTypeScreenScheme >>

  my $res = $client->getProjectsForIssueTypeScreenScheme()->get;

Get issue type screen scheme projects

=head3 Parameters

=over 4

=item B<< issueTypeScreenSchemeId >>

The ID of the issue type screen scheme.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< query >>

=back


Returns a L<< JIRA::API::PageBeanProjectDetails >>.

=cut

sub _build_getProjectsForIssueTypeScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'issueTypeScreenSchemeId'"
        unless exists $options{ 'issueTypeScreenSchemeId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/issuetypescreenscheme/{issueTypeScreenSchemeId}/project' );
    my $path = $template->process(
              'issueTypeScreenSchemeId' => delete $options{'issueTypeScreenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'query' => delete $options{'query'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectsForIssueTypeScreenScheme( $self, %options ) {
    my $tx = $self->_build_getProjectsForIssueTypeScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanProjectDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAutoComplete >>

  my $res = $client->getAutoComplete()->get;

Get field reference data (GET)

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::JQLReferenceData >>.

=cut

sub _build_getAutoComplete_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/jql/autocompletedata';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAutoComplete( $self, %options ) {
    my $tx = $self->_build_getAutoComplete_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::JQLReferenceData->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAutoCompletePost >>

  my $res = $client->getAutoCompletePost()->get;

Get field reference data (POST)

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< includeCollapsedFields >>

Include collapsed fields for fields that have non-unique names.

=item C<< projectIds >>

List of project IDs used to filter the visible field details returned.

=back

Returns a L<< JIRA::API::JQLReferenceData >>.

=cut

sub _build_getAutoCompletePost_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/jql/autocompletedata';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::SearchAutoCompleteFilter->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getAutoCompletePost( $self, %options ) {
    my $tx = $self->_build_getAutoCompletePost_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::JQLReferenceData->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFieldAutoCompleteForQueryString >>

  my $res = $client->getFieldAutoCompleteForQueryString()->get;

Get field auto complete suggestions

=head3 Parameters

=over 4

=item B<< fieldName >>

The name of the field.

=item B<< fieldValue >>

The partial field item name entered by the user.

=item B<< predicateName >>

The name of the L< CHANGED operator predicate|https://confluence.atlassian.com/x/hQORLQ#Advancedsearching-operatorsreference-CHANGEDCHANGED> for which the suggestions are generated. The valid predicate operators are I<by>, I<from>, and I<to>.

=item B<< predicateValue >>

The partial predicate item name entered by the user.

=back


Returns a L<< JIRA::API::AutoCompleteSuggestions >>.

=cut

sub _build_getFieldAutoCompleteForQueryString_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/jql/autocompletedata/suggestions';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'fieldName' => delete $options{'fieldName'},
        maybe 'fieldValue' => delete $options{'fieldValue'},
        maybe 'predicateName' => delete $options{'predicateName'},
        maybe 'predicateValue' => delete $options{'predicateValue'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFieldAutoCompleteForQueryString( $self, %options ) {
    my $tx = $self->_build_getFieldAutoCompleteForQueryString_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::AutoCompleteSuggestions->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if an invalid combination of parameters is passed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPrecomputations >>

  my $res = $client->getPrecomputations()->get;

Get precomputation

=head3 Parameters

=over 4

=item B<< functionKey >>

=item B<< startAt >>

=item B<< maxResults >>

=item B<< orderBy >>

=item B<< filter >>

=back


Returns a L<< JIRA::API::PageBeanJqlFunctionPrecomputationBean >>.

=cut

sub _build_getPrecomputations_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/jql/function/computation';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'functionKey' => delete $options{'functionKey'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'filter' => delete $options{'filter'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPrecomputations( $self, %options ) {
    my $tx = $self->_build_getPrecomputations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanJqlFunctionPrecomputationBean->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updatePrecomputations >>

  my $res = $client->updatePrecomputations()->get;

Update precomputations

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< values >>

=back

Returns a L<<  >>.

=cut

sub _build_updatePrecomputations_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/jql/function/computation';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::JqlFunctionPrecomputationUpdateRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updatePrecomputations( $self, %options ) {
    my $tx = $self->_build_updatePrecomputations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< matchIssues >>

  my $res = $client->matchIssues()->get;

Check issues against JQL

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< issueIds >>

A list of issue IDs.

=item C<< jqls >>

A list of JQL queries.

=back

Returns a L<< JIRA::API::IssueMatches >>.

=cut

sub _build_matchIssues_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/jql/match';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssuesAndJQLQueries->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub matchIssues( $self, %options ) {
    my $tx = $self->_build_matchIssues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueMatches->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `jqls` exceeds the maximum number of JQL queries or `issueIds` exceeds the maximum number of issue IDs.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< parseJqlQueries >>

  my $res = $client->parseJqlQueries()->get;

Parse JQL query

=head3 Parameters

=over 4

=item B<< validation >>

How to validate the JQL query and treat the validation results. Validation options include:

=over

=item *

C<strict> Returns all errors. If validation fails, the query structure is not returned.


=item *

C<warn> Returns all errors. If validation fails but the JQL query is correctly formed, the query structure is returned.


=item *

C<none> No validation is performed. If JQL query is correctly formed, the query structure is returned.


=back

=back


=head3 Options

=over 4

=item C<< queries >>

A list of queries to parse.

=back

Returns a L<< JIRA::API::ParsedJqlQueries >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_parseJqlQueries_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/jql/parse';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'validation' => delete $options{'validation'},
    );

    my $request = JIRA::API::JqlQueriesToParse->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub parseJqlQueries( $self, %options ) {
    my $tx = $self->_build_parseJqlQueries_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ParsedJqlQueries->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< migrateQueries >>

  my $res = $client->migrateQueries()->get;

Convert user identifiers to account IDs in JQL queries

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< queryStrings >>

A list of queries with user identifiers. Maximum of 100 queries.

=back

Returns a L<< JIRA::API::ConvertedJQLQueries >>.

=cut

sub _build_migrateQueries_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/jql/pdcleaner';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::JQLPersonalDataMigrationRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub migrateQueries( $self, %options ) {
    my $tx = $self->_build_migrateQueries_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful. Note that the JQL queries are returned in the same order that they were passed.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ConvertedJQLQueries->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if at least one of the queries cannot be converted. For example, the JQL has invalid operators or invalid keywords, or the users in the query cannot be found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< sanitiseJqlQueries >>

  my $res = $client->sanitiseJqlQueries()->get;

Sanitize JQL queries

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< queries >>

The list of JQL queries to sanitize. Must contain unique values. Maximum of 20 queries.

=back

Returns a L<< JIRA::API::SanitizedJqlQueries >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_sanitiseJqlQueries_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/jql/sanitize';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::JqlQueriesToSanitize->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub sanitiseJqlQueries( $self, %options ) {
    my $tx = $self->_build_sanitiseJqlQueries_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SanitizedJqlQueries->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllLabels >>

  my $res = $client->getAllLabels()->get;

Get all labels

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanString >>.

=cut

sub _build_getAllLabels_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/label';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllLabels( $self, %options ) {
    my $tx = $self->_build_getAllLabels_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanString->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getApproximateLicenseCount >>

  my $res = $client->getApproximateLicenseCount()->get;

Get approximate license count

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::LicenseMetric >>.

=cut

sub _build_getApproximateLicenseCount_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/license/approximateLicenseCount';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getApproximateLicenseCount( $self, %options ) {
    my $tx = $self->_build_getApproximateLicenseCount_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::LicenseMetric->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to complete this request.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getApproximateApplicationLicenseCount >>

  my $res = $client->getApproximateApplicationLicenseCount()->get;

Get approximate application license count

=head3 Parameters

=over 4

=item B<< applicationKey >>

=back


Returns a L<< JIRA::API::LicenseMetric >>.

=cut

sub _build_getApproximateApplicationLicenseCount_request( $self, %options ) {
    croak "Missing required parameter 'applicationKey'"
        unless exists $options{ 'applicationKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/license/approximateLicenseCount/product/{applicationKey}' );
    my $path = $template->process(
              'applicationKey' => delete $options{'applicationKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getApproximateApplicationLicenseCount( $self, %options ) {
    my $tx = $self->_build_getApproximateApplicationLicenseCount_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::LicenseMetric->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to complete this request.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getMyPermissions >>

  my $res = $client->getMyPermissions()->get;

Get my permissions

=head3 Parameters

=over 4

=item B<< projectKey >>

The key of project. Ignored if C<projectId> is provided.

=item B<< projectId >>

The ID of project.

=item B<< issueKey >>

The key of the issue. Ignored if C<issueId> is provided.

=item B<< issueId >>

The ID of the issue.

=item B<< permissions >>

A list of permission keys. (Required) This parameter accepts a comma-separated list. To get the list of available permissions, use L<Get all permissions|#api-rest-api-3-permissions-get>.

=item B<< projectUuid >>

=item B<< projectConfigurationUuid >>

=item B<< commentId >>

The ID of the comment.

=back


Returns a L<< JIRA::API::Permissions >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getMyPermissions_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/mypermissions';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'projectKey' => delete $options{'projectKey'},
        maybe 'projectId' => delete $options{'projectId'},
        maybe 'issueKey' => delete $options{'issueKey'},
        maybe 'issueId' => delete $options{'issueId'},
        maybe 'permissions' => delete $options{'permissions'},
        maybe 'projectUuid' => delete $options{'projectUuid'},
        maybe 'projectConfigurationUuid' => delete $options{'projectConfigurationUuid'},
        maybe 'commentId' => delete $options{'commentId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getMyPermissions( $self, %options ) {
    my $tx = $self->_build_getMyPermissions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Permissions->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `permissions` is empty, contains an invalid key, or does not equal BROWSE\_PROJECTS when commentId is provided.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the project or issue is not found or the user does not have permission to view the project or issue.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removePreference >>

  my $res = $client->removePreference()->get;

Delete preference

=head3 Parameters

=over 4

=item B<< key >>

The key of the preference.

=back



=cut

sub _build_removePreference_request( $self, %options ) {
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };

    my $method = 'DELETE';
    my $path = '/rest/api/3/mypreferences';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removePreference( $self, %options ) {
    my $tx = $self->_build_removePreference_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the key is not provided or not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPreference >>

  my $res = $client->getPreference()->get;

Get preference

=head3 Parameters

=over 4

=item B<< key >>

The key of the preference.

=back


Returns a L<< string >>.

=cut

sub _build_getPreference_request( $self, %options ) {
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };

    my $method = 'GET';
    my $path = '/rest/api/3/mypreferences';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPreference( $self, %options ) {
    my $tx = $self->_build_getPreference_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the key is not provided or not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setPreference >>

  my $res = $client->setPreference()->get;

Set preference

=head3 Parameters

=over 4

=item B<< key >>

The key of the preference. The maximum length is 255 characters.

=back


Returns a L<<  >>.

=cut

sub _build_setPreference_request( $self, %options ) {
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };

    my $method = 'PUT';
    my $path = '/rest/api/3/mypreferences';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'key' => delete $options{'key'},
    );

    my $body = delete $options{ body } // '';
    my $body = delete $options{ body } // '';
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setPreference( $self, %options ) {
    my $tx = $self->_build_setPreference_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the key or value is not provided or invalid.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteLocale >>

  my $res = $client->deleteLocale()->get;

Delete locale

=head3 Parameters

=over 4

=back


Returns a L<<  >>.

=cut

sub _build_deleteLocale_request( $self, %options ) {
    my $method = 'DELETE';
    my $path = '/rest/api/3/mypreferences/locale';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteLocale( $self, %options ) {
    my $tx = $self->_build_deleteLocale_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getLocale >>

  my $res = $client->getLocale()->get;

Get locale

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::Locale >>.

=cut

sub _build_getLocale_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/mypreferences/locale';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getLocale( $self, %options ) {
    my $tx = $self->_build_getLocale_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Locale->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setLocale >>

  my $res = $client->setLocale()->get;

Set locale

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< locale >>

The locale code. The Java the locale format is used: a two character language code (ISO 639), an underscore, and two letter country code (ISO 3166). For example, en_US represents a locale of English (United States). Required on create.

=back

Returns a L<<  >>.

=cut

sub _build_setLocale_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/mypreferences/locale';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::Locale->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setLocale( $self, %options ) {
    my $tx = $self->_build_setLocale_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getCurrentUser >>

  my $res = $client->getCurrentUser()->get;

Get current user

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about user in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<groups> Returns all groups, including nested groups, the user belongs to.


=item *

C<applicationRoles> Returns the application roles the user is assigned to.


=back

=back


Returns a L<< JIRA::API::User >>.

=cut

sub _build_getCurrentUser_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/myself';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getCurrentUser( $self, %options ) {
    my $tx = $self->_build_getCurrentUser_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::User->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getNotificationSchemes >>

  my $res = $client->getNotificationSchemes()->get;

Get notification schemes paginated

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of notification schemes IDs to be filtered by

=item B<< projectId >>

The list of projects IDs to be filtered by

=item B<< onlyDefault >>

When set to true, returns only the default notification scheme. If you provide project IDs not associated with the default, returns an empty page. The default value is false.

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<all> Returns all expandable information


=item *

C<field> Returns information about any custom fields assigned to receive an event


=item *

C<group> Returns information about any groups assigned to receive an event


=item *

C<notificationSchemeEvents> Returns a list of event associations. This list is returned for all expandable information


=item *

C<projectRole> Returns information about any project roles assigned to receive an event


=item *

C<user> Returns information about any users assigned to receive an event


=back

=back


Returns a L<< JIRA::API::PageBeanNotificationScheme >>.

=cut

sub _build_getNotificationSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/notificationscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'projectId' => delete $options{'projectId'},
        maybe 'onlyDefault' => delete $options{'onlyDefault'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getNotificationSchemes( $self, %options ) {
    my $tx = $self->_build_getNotificationSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful. Only returns notification schemes that the user has permission to access. An empty list is returned if the user lacks permission to access all notification schemes.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanNotificationScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createNotificationScheme >>

  my $res = $client->createNotificationScheme()->get;

Create notification scheme

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the notification scheme.

=item C<< name >>

The name of the notification scheme. Must be unique (case-insensitive).

=item C<< notificationSchemeEvents >>

The list of notifications which should be added to the notification scheme.

=back

Returns a L<< JIRA::API::NotificationSchemeId >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_createNotificationScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/notificationscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateNotificationSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createNotificationScheme( $self, %options ) {
    my $tx = $self->_build_createNotificationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::NotificationSchemeId->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getNotificationSchemeToProjectMappings >>

  my $res = $client->getNotificationSchemeToProjectMappings()->get;

Get projects using notification schemes paginated

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< notificationSchemeId >>

The list of notifications scheme IDs to be filtered out

=item B<< projectId >>

The list of project IDs to be filtered out

=back


Returns a L<< JIRA::API::PageBeanNotificationSchemeAndProjectMappingJsonBean >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getNotificationSchemeToProjectMappings_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/notificationscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'notificationSchemeId' => delete $options{'notificationSchemeId'},
        maybe 'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getNotificationSchemeToProjectMappings( $self, %options ) {
    my $tx = $self->_build_getNotificationSchemeToProjectMappings_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanNotificationSchemeAndProjectMappingJsonBean->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if search criteria are invalid, strings vs numbers for projectId, notificationSchemeId, startAt and maxResult
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getNotificationScheme >>

  my $res = $client->getNotificationScheme()->get;

Get notification scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the notification scheme. Use L<Get notification schemes paginated|#api-rest-api-3-notificationscheme-get> to get a list of notification scheme IDs.

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<all> Returns all expandable information


=item *

C<field> Returns information about any custom fields assigned to receive an event


=item *

C<group> Returns information about any groups assigned to receive an event


=item *

C<notificationSchemeEvents> Returns a list of event associations. This list is returned for all expandable information


=item *

C<projectRole> Returns information about any project roles assigned to receive an event


=item *

C<user> Returns information about any users assigned to receive an event


=back

=back


Returns a L<< JIRA::API::NotificationScheme >>.

=cut

sub _build_getNotificationScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/notificationscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getNotificationScheme( $self, %options ) {
    my $tx = $self->_build_getNotificationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::NotificationScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the notification scheme is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateNotificationScheme >>

  my $res = $client->updateNotificationScheme()->get;

Update notification scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the notification scheme.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the notification scheme.

=item C<< name >>

The name of the notification scheme. Must be unique.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_updateNotificationScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/notificationscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateNotificationSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateNotificationScheme( $self, %options ) {
    my $tx = $self->_build_updateNotificationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the notification scheme isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addNotifications >>

  my $res = $client->addNotifications()->get;

Add notifications to notification scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the notification scheme.

=back


=head3 Options

=over 4

=item C<< notificationSchemeEvents >>

The list of notifications which should be added to the notification scheme.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_addNotifications_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/notificationscheme/{id}/notification' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::AddNotificationsDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addNotifications( $self, %options ) {
    my $tx = $self->_build_addNotifications_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the notification scheme isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteNotificationScheme >>

  my $res = $client->deleteNotificationScheme()->get;

Delete notification scheme

=head3 Parameters

=over 4

=item B<< notificationSchemeId >>

The ID of the notification scheme.

=back


Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deleteNotificationScheme_request( $self, %options ) {
    croak "Missing required parameter 'notificationSchemeId'"
        unless exists $options{ 'notificationSchemeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/notificationscheme/{notificationSchemeId}' );
    my $path = $template->process(
              'notificationSchemeId' => delete $options{'notificationSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteNotificationScheme( $self, %options ) {
    my $tx = $self->_build_deleteNotificationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the notification scheme isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeNotificationFromNotificationScheme >>

  my $res = $client->removeNotificationFromNotificationScheme()->get;

Remove notification from notification scheme

=head3 Parameters

=over 4

=item B<< notificationSchemeId >>

The ID of the notification scheme.

=item B<< notificationId >>

The ID of the notification.

=back


Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_removeNotificationFromNotificationScheme_request( $self, %options ) {
    croak "Missing required parameter 'notificationSchemeId'"
        unless exists $options{ 'notificationSchemeId' };
    croak "Missing required parameter 'notificationId'"
        unless exists $options{ 'notificationId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/notificationscheme/{notificationSchemeId}/notification/{notificationId}' );
    my $path = $template->process(
              'notificationSchemeId' => delete $options{'notificationSchemeId'},
              'notificationId' => delete $options{'notificationId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub removeNotificationFromNotificationScheme( $self, %options ) {
    my $tx = $self->_build_removeNotificationFromNotificationScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if either the notification scheme or notification isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllPermissions >>

  my $res = $client->getAllPermissions()->get;

Get all permissions

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::Permissions >>.

=cut

sub _build_getAllPermissions_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/permissions';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllPermissions( $self, %options ) {
    my $tx = $self->_build_getAllPermissions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Permissions->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getBulkPermissions >>

  my $res = $client->getBulkPermissions()->get;

Get bulk permissions

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< accountId >>

The account ID of a user.

=item C<< globalPermissions >>

Global permissions to look up.

=item C<< projectPermissions >>

Project permissions with associated projects and issues to look up.

=back

Returns a L<< JIRA::API::BulkPermissionGrants >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getBulkPermissions_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/permissions/check';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::BulkPermissionsRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getBulkPermissions( $self, %options ) {
    my $tx = $self->_build_getBulkPermissions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::BulkPermissionGrants->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `projectPermissions` is provided without at least one project permission being provided. * an invalid global permission is provided in the global permissions list. * an invalid project permission is provided in the project permissions list. * more than 1000 valid project IDs or more than 1000 valid issue IDs are provided. * an invalid account ID is provided.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPermittedProjects >>

  my $res = $client->getPermittedProjects()->get;

Get permitted projects

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< permissions >>

A list of permission keys.

=back

Returns a L<< JIRA::API::PermittedProjects >>.

=cut

sub _build_getPermittedProjects_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/permissions/project';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::PermissionsKeysBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getPermittedProjects( $self, %options ) {
    my $tx = $self->_build_getPermittedProjects_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermittedProjects->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if a project permission is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllPermissionSchemes >>

  my $res = $client->getAllPermissionSchemes()->get;

Get all permission schemes

=head3 Parameters

=over 4

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


Returns a L<< JIRA::API::PermissionSchemes >>.

=cut

sub _build_getAllPermissionSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/permissionscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllPermissionSchemes( $self, %options ) {
    my $tx = $self->_build_getAllPermissionSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionSchemes->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createPermissionScheme >>

  my $res = $client->createPermissionScheme()->get;

Create permission scheme

=head3 Parameters

=over 4

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are always included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


=head3 Options

=over 4

=item C<< description >>

A description for the permission scheme.

=item C<< expand >>

The expand options available for the permission scheme.

=item C<< id >>

The ID of the permission scheme.

=item C<< name >>

The name of the permission scheme. Must be unique.

=item C<< permissions >>

The permission scheme to create or update. See L<About permission schemes and grants|../api-group-permission-schemes/#about-permission-schemes-and-grants> for more information.

=item C<< scope >>

The scope of the permission scheme.

=item C<< self >>

The URL of the permission scheme.

=back

Returns a L<< JIRA::API::PermissionScheme >>.

=cut

sub _build_createPermissionScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/permissionscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::PermissionScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createPermissionScheme( $self, %options ) {
    my $tx = $self->_build_createPermissionScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the permission scheme is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or the feature is not available in the Jira plan.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deletePermissionScheme >>

  my $res = $client->deletePermissionScheme()->get;

Delete permission scheme

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme being deleted.

=back



=cut

sub _build_deletePermissionScheme_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deletePermissionScheme( $self, %options ) {
    my $tx = $self->_build_deletePermissionScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the permission scheme is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the permission scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPermissionScheme >>

  my $res = $client->getPermissionScheme()->get;

Get permission scheme

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme to return.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


Returns a L<< JIRA::API::PermissionScheme >>.

=cut

sub _build_getPermissionScheme_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPermissionScheme( $self, %options ) {
    my $tx = $self->_build_getPermissionScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the permission scheme is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updatePermissionScheme >>

  my $res = $client->updatePermissionScheme()->get;

Update permission scheme

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme to update.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are always included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


=head3 Options

=over 4

=item C<< description >>

A description for the permission scheme.

=item C<< expand >>

The expand options available for the permission scheme.

=item C<< id >>

The ID of the permission scheme.

=item C<< name >>

The name of the permission scheme. Must be unique.

=item C<< permissions >>

The permission scheme to create or update. See L<About permission schemes and grants|../api-group-permission-schemes/#about-permission-schemes-and-grants> for more information.

=item C<< scope >>

The scope of the permission scheme.

=item C<< self >>

The URL of the permission scheme.

=back

Returns a L<< JIRA::API::PermissionScheme >>.

=cut

sub _build_updatePermissionScheme_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::PermissionScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updatePermissionScheme( $self, %options ) {
    my $tx = $self->_build_updatePermissionScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the scheme is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if: * the user does not have the necessary permission to update permission schemes. * the Jira instance is Jira Core Free or Jira Software Free. Permission schemes cannot be updated on free plans.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the permission scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPermissionSchemeGrants >>

  my $res = $client->getPermissionSchemeGrants()->get;

Get permission scheme grants

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are always included when you specify any value. Expand options include:

=over

=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<user> Returns information about the user who is granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<all> Returns all expandable information.


=back

=back


Returns a L<< JIRA::API::PermissionGrants >>.

=cut

sub _build_getPermissionSchemeGrants_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}/permission' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPermissionSchemeGrants( $self, %options ) {
    my $tx = $self->_build_getPermissionSchemeGrants_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionGrants->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the permission schemes is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createPermissionGrant >>

  my $res = $client->createPermissionGrant()->get;

Create permission grant

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme in which to create a new permission grant.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are always included when you specify any value. Expand options include:

=over

=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<user> Returns information about the user who is granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<all> Returns all expandable information.


=back

=back


=head3 Options

=over 4

=item C<< holder >>

The user or group being granted the permission. It consists of a C<type>, a type-dependent C<parameter> and a type-dependent C<value>. See L<Holder object|../api-group-permission-schemes/#holder-object> in I<Get all permission schemes> for more information.

=item C<< id >>

The ID of the permission granted details.

=item C<< permission >>

The permission to grant. This permission can be one of the built-in permissions or a custom permission added by an app. See L<Built-in permissions|../api-group-permission-schemes/#built-in-permissions> in I<Get all permission schemes> for more information about the built-in permissions. See the L<project permission|https://developer.atlassian.com/cloud/jira/platform/modules/project-permission/> and L<global permission|https://developer.atlassian.com/cloud/jira/platform/modules/global-permission/> module documentation for more information about custom permissions.

=item C<< self >>

The URL of the permission granted details.

=back

Returns a L<< JIRA::API::PermissionGrant >>.

=cut

sub _build_createPermissionGrant_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}/permission' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::PermissionGrant->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createPermissionGrant( $self, %options ) {
    my $tx = $self->_build_createPermissionGrant_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the scheme permission is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionGrant->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the value for expand is invalid or the same permission grant is present.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deletePermissionSchemeEntity >>

  my $res = $client->deletePermissionSchemeEntity()->get;

Delete permission scheme grant

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme to delete the permission grant from.

=item B<< permissionId >>

The ID of the permission grant to delete.

=back



=cut

sub _build_deletePermissionSchemeEntity_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };
    croak "Missing required parameter 'permissionId'"
        unless exists $options{ 'permissionId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}/permission/{permissionId}' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
              'permissionId' => delete $options{'permissionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deletePermissionSchemeEntity( $self, %options ) {
    my $tx = $self->_build_deletePermissionSchemeEntity_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the permission grant is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if permission grant with the provided ID is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPermissionSchemeGrant >>

  my $res = $client->getPermissionSchemeGrant()->get;

Get permission scheme grant

=head3 Parameters

=over 4

=item B<< schemeId >>

The ID of the permission scheme.

=item B<< permissionId >>

The ID of the permission grant.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are always included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


Returns a L<< JIRA::API::PermissionGrant >>.

=cut

sub _build_getPermissionSchemeGrant_request( $self, %options ) {
    croak "Missing required parameter 'schemeId'"
        unless exists $options{ 'schemeId' };
    croak "Missing required parameter 'permissionId'"
        unless exists $options{ 'permissionId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/permissionscheme/{schemeId}/permission/{permissionId}' );
    my $path = $template->process(
              'schemeId' => delete $options{'schemeId'},
              'permissionId' => delete $options{'permissionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPermissionSchemeGrant( $self, %options ) {
    my $tx = $self->_build_getPermissionSchemeGrant_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionGrant->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the permission scheme or permission grant is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPriorities >>

  my $res = $client->getPriorities()->get;

Get priorities

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::Priority >>.

=cut

sub _build_getPriorities_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/priority';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPriorities( $self, %options ) {
    my $tx = $self->_build_getPriorities_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Priority->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createPriority >>

  my $res = $client->createPriority()->get;

Create priority

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the priority.

=item C<< iconUrl >>

The URL of an icon for the priority. Accepted protocols are HTTP and HTTPS. Built in icons can also be used.

=item C<< name >>

The name of the priority. Must be unique.

=item C<< statusColor >>

The status color of the priority in 3-digit or 6-digit hexadecimal format.

=back

Returns a L<< JIRA::API::PriorityId >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_createPriority_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/priority';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreatePriorityDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createPriority( $self, %options ) {
    my $tx = $self->_build_createPriority_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PriorityId->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setDefaultPriority >>

  my $res = $client->setDefaultPriority()->get;

Set default priority

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the new default issue priority. Must be an existing ID or null. Setting this to null erases the default priority setting.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_setDefaultPriority_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/priority/default';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::SetDefaultPriorityRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setDefaultPriority( $self, %options ) {
    my $tx = $self->_build_setDefaultPriority_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue priority isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< movePriorities >>

  my $res = $client->movePriorities()->get;

Move priorities

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< after >>

The ID of the priority. Required if C<position> isn't provided.

=item C<< ids >>

The list of issue IDs to be reordered. Cannot contain duplicates nor after ID.

=item C<< position >>

The position for issue priorities to be moved to. Required if C<after> isn't provided.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_movePriorities_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/priority/move';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ReorderIssuePriorities->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub movePriorities( $self, %options ) {
    my $tx = $self->_build_movePriorities_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue priority isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< searchPriorities >>

  my $res = $client->searchPriorities()->get;

Search priorities

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of priority IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=2&id=3>.

=item B<< onlyDefault >>

Whether only the default priority is returned.

=back


Returns a L<< JIRA::API::PageBeanPriority >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_searchPriorities_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/priority/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'onlyDefault' => delete $options{'onlyDefault'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub searchPriorities( $self, %options ) {
    my $tx = $self->_build_searchPriorities_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanPriority->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deletePriority >>

  my $res = $client->deletePriority()->get;

Delete priority

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue priority.

=item B<< replaceWith >>

The ID of the issue priority that will replace the currently selected resolution.

=back


Returns a L<< JIRA::API::TaskProgressBeanObject >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deletePriority_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'replaceWith'"
        unless exists $options{ 'replaceWith' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/priority/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'replaceWith' => delete $options{'replaceWith'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deletePriority( $self, %options ) {
    my $tx = $self->_build_deletePriority_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanObject->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue priority isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if a task to delete the issue priority is already running.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getPriority >>

  my $res = $client->getPriority()->get;

Get priority

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue priority.

=back


Returns a L<< JIRA::API::Priority >>.

=cut

sub _build_getPriority_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/priority/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getPriority( $self, %options ) {
    my $tx = $self->_build_getPriority_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Priority->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue priority isn't found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updatePriority >>

  my $res = $client->updatePriority()->get;

Update priority

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue priority.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the priority.

=item C<< iconUrl >>

The URL of an icon for the priority. Accepted protocols are HTTP and HTTPS. Built in icons can also be used.

=item C<< name >>

The name of the priority. Must be unique.

=item C<< statusColor >>

The status color of the priority in 3-digit or 6-digit hexadecimal format.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_updatePriority_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/priority/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdatePriorityDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updatePriority( $self, %options ) {
    my $tx = $self->_build_updatePriority_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue priority isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllProjects >>

  my $res = $client->getAllProjects()->get;

Get all projects

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expanded options include:

=over

=item *

C<description> Returns the project description.


=item *

C<issueTypes> Returns all issue types associated with the project.


=item *

C<lead> Returns information about the project lead.


=item *

C<projectKeys> Returns all project keys associated with the project.


=back

=item B<< recent >>

Returns the user's most recently accessed projects. You may specify the number of results to return up to a maximum of 20. If access is anonymous, then the recently accessed projects are based on the current HTTP session.

=item B<< properties >>

A list of project properties to return for the project. This parameter accepts a comma-separated list.

=back


Returns an array of L<< JIRA::API::Project >>.

=cut

sub _build_getAllProjects_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'recent' => delete $options{'recent'},
        maybe 'properties' => delete $options{'properties'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllProjects( $self, %options ) {
    my $tx = $self->_build_getAllProjects_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Project->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createProject >>

  my $res = $client->createProject()->get;

Create project

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< assigneeType >>

The default assignee when creating issues for this project.

=item C<< avatarId >>

An integer value for the project's avatar.

=item C<< categoryId >>

The ID of the project's category. A complete list of category IDs is found using the L<Get all project categories|#api-rest-api-3-projectCategory-get> operation.

=item C<< description >>

A brief description of the project.

=item C<< fieldConfigurationScheme >>

The ID of the field configuration scheme for the project. Use the L<Get all field configuration schemes|#api-rest-api-3-fieldconfigurationscheme-get> operation to get a list of field configuration scheme IDs. If you specify the field configuration scheme you cannot specify the project template key.

=item C<< issueSecurityScheme >>

The ID of the issue security scheme for the project, which enables you to control who can and cannot view issues. Use the L<Get issue security schemes|#api-rest-api-3-issuesecurityschemes-get> resource to get all issue security scheme IDs.

=item C<< issueTypeScheme >>

The ID of the issue type scheme for the project. Use the L<Get all issue type schemes|#api-rest-api-3-issuetypescheme-get> operation to get a list of issue type scheme IDs. If you specify the issue type scheme you cannot specify the project template key.

=item C<< issueTypeScreenScheme >>

The ID of the issue type screen scheme for the project. Use the L<Get all issue type screen schemes|#api-rest-api-3-issuetypescreenscheme-get> operation to get a list of issue type screen scheme IDs. If you specify the issue type screen scheme you cannot specify the project template key.

=item C<< key >>

Project keys must be unique and start with an uppercase letter followed by one or more uppercase alphanumeric characters. The maximum length is 10 characters.

=item C<< lead >>

This parameter is deprecated because of privacy changes. Use C<leadAccountId> instead. See the L<migration guide|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details. The user name of the project lead. Either C<lead> or C<leadAccountId> must be set when creating a project. Cannot be provided with C<leadAccountId>.

=item C<< leadAccountId >>

The account ID of the project lead. Either C<lead> or C<leadAccountId> must be set when creating a project. Cannot be provided with C<lead>.

=item C<< name >>

The name of the project.

=item C<< notificationScheme >>

The ID of the notification scheme for the project. Use the L<Get notification schemes|#api-rest-api-3-notificationscheme-get> resource to get a list of notification scheme IDs.

=item C<< permissionScheme >>

The ID of the permission scheme for the project. Use the L<Get all permission schemes|#api-rest-api-3-permissionscheme-get> resource to see a list of all permission scheme IDs.

=item C<< projectTemplateKey >>

A predefined configuration for a project. The type of the C<projectTemplateKey> must match with the type of the C<projectTypeKey>.

=item C<< projectTypeKey >>

The L<project type|https://confluence.atlassian.com/x/GwiiLQ#Jiraapplicationsoverview-Productfeaturesandprojecttypes>, which defines the application-specific feature set. If you don't specify the project template you have to specify the project type.

=item C<< url >>

A link to information about this project, such as project documentation

=item C<< workflowScheme >>

The ID of the workflow scheme for the project. Use the L<Get all workflow schemes|#api-rest-api-3-workflowscheme-get> operation to get a list of workflow scheme IDs. If you specify the workflow scheme you cannot specify the project template key.

=back

Returns a L<< JIRA::API::ProjectIdentifiers >>.

=cut

sub _build_createProject_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/project';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateProjectDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createProject( $self, %options ) {
    my $tx = $self->_build_createProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the project is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectIdentifiers->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid and the project could not be created.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to create projects.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getRecent >>

  my $res = $client->getRecent()->get;

Get recent projects

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expanded options include:

=over

=item *

C<description> Returns the project description.


=item *

C<projectKeys> Returns all project keys associated with a project.


=item *

C<lead> Returns information about the project lead.


=item *

C<issueTypes> Returns all issue types associated with the project.


=item *

C<url> Returns the URL associated with the project.


=item *

C<permissions> Returns the permissions associated with the project.


=item *

C<insight> EXPERIMENTAL. Returns the insight details of total issue count and last issue update time for the project.


=item *

C<*> Returns the project with all available expand options.


=back

=item B<< properties >>

EXPERIMENTAL. A list of project properties to return for the project. This parameter accepts a comma-separated list. Invalid property names are ignored.

=back


Returns an array of L<< JIRA::API::Project >>.

=cut

sub _build_getRecent_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/project/recent';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'properties' => delete $options{'properties'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getRecent( $self, %options ) {
    my $tx = $self->_build_getRecent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Project->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< searchProjects >>

  my $res = $client->searchProjects()->get;

Get projects paginated

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< orderBy >>

L<Order|#ordering> the results by a field.

=over

=item *

C<category> Sorts by project category. A complete list of category IDs is found using L<Get all project categories|#api-rest-api-3-projectCategory-get>.


=item *

C<issueCount> Sorts by the total number of issues in each project.


=item *

C<key> Sorts by project key.


=item *

C<lastIssueUpdatedTime> Sorts by the last issue update time.


=item *

C<name> Sorts by project name.


=item *

C<owner> Sorts by project lead.


=item *

C<archivedDate> EXPERIMENTAL. Sorts by project archived date.


=item *

C<deletedDate> EXPERIMENTAL. Sorts by project deleted date.


=back

=item B<< id >>

The project IDs to filter the results by. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>. Up to 50 project IDs can be provided.

=item B<< keys >>

The project keys to filter the results by. To include multiple keys, provide an ampersand-separated list. For example, C<keys=PA&keys=PB>. Up to 50 project keys can be provided.

=item B<< query >>

Filter the results using a literal string. Projects with a matching C<key> or C<name> are returned (case insensitive).

=item B<< typeKey >>

Orders results by the L<project type|https://confluence.atlassian.com/x/GwiiLQ#Jiraapplicationsoverview-Productfeaturesandprojecttypes>. This parameter accepts a comma-separated list. Valid values are C<business>, C<service_desk>, and C<software>.

=item B<< categoryId >>

The ID of the project's category. A complete list of category IDs is found using the L<Get all project categories|#api-rest-api-3-projectCategory-get> operation.

=item B<< action >>

Filter results by projects for which the user can:

=over

=item *

C<view> the project, meaning that they have one of the following permissions:


=over

=item *

I<Browse projects> L<project permission|https://confluence.atlassian.com/x/yodKLg> for the project.


=item *

I<Administer projects> L<project permission|https://confluence.atlassian.com/x/yodKLg> for the project.


=item *

I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.


=back



=item *

C<browse> the project, meaning that they have the I<Browse projects> L<project permission|https://confluence.atlassian.com/x/yodKLg> for the project.


=item *

C<edit> the project, meaning that they have one of the following permissions:


=over

=item *

I<Administer projects> L<project permission|https://confluence.atlassian.com/x/yodKLg> for the project.


=item *

I<Administer Jira> L<global permission|https://confluence.atlassian.com/x/x4dKLg>.


=back



=back

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expanded options include:

=over

=item *

C<description> Returns the project description.


=item *

C<projectKeys> Returns all project keys associated with a project.


=item *

C<lead> Returns information about the project lead.


=item *

C<issueTypes> Returns all issue types associated with the project.


=item *

C<url> Returns the URL associated with the project.


=item *

C<insight> EXPERIMENTAL. Returns the insight details of total issue count and last issue update time for the project.


=back

=item B<< status >>

EXPERIMENTAL. Filter results by project status:

=over

=item *

C<live> Search live projects.


=item *

C<archived> Search archived projects.


=item *

C<deleted> Search deleted projects, those in the recycle bin.


=back

=item B<< properties >>

EXPERIMENTAL. A list of project properties to return for the project. This parameter accepts a comma-separated list.

=item B<< propertyQuery >>

EXPERIMENTAL. A query string used to search properties. The query string cannot be specified using a JSON object. For example, to search for the value of C<nested> from C<{"something":{"nested":1,"other":2}}> use C<[thepropertykey].something.nested=1>. Note that the propertyQuery key is enclosed in square brackets to enable searching where the propertyQuery key includes dot (.) or equals (=) characters. Note that C<thepropertykey> is only returned when included in C<properties>.

=back


Returns a L<< JIRA::API::PageBeanProject >>.

=cut

sub _build_searchProjects_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/project/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'id' => delete $options{'id'},
        maybe 'keys' => delete $options{'keys'},
        maybe 'query' => delete $options{'query'},
        maybe 'typeKey' => delete $options{'typeKey'},
        maybe 'categoryId' => delete $options{'categoryId'},
        maybe 'action' => delete $options{'action'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'status' => delete $options{'status'},
        maybe 'properties' => delete $options{'properties'},
        maybe 'propertyQuery' => delete $options{'propertyQuery'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub searchProjects( $self, %options ) {
    my $tx = $self->_build_searchProjects_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanProject->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if no projects matching the search criteria are found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllProjectTypes >>

  my $res = $client->getAllProjectTypes()->get;

Get all project types

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ProjectType >>.

=cut

sub _build_getAllProjectTypes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/project/type';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllProjectTypes( $self, %options ) {
    my $tx = $self->_build_getAllProjectTypes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ProjectType->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllAccessibleProjectTypes >>

  my $res = $client->getAllAccessibleProjectTypes()->get;

Get licensed project types

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ProjectType >>.

=cut

sub _build_getAllAccessibleProjectTypes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/project/type/accessible';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllAccessibleProjectTypes( $self, %options ) {
    my $tx = $self->_build_getAllAccessibleProjectTypes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ProjectType->new($_),
 } $payload->@* ],

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectTypeByKey >>

  my $res = $client->getProjectTypeByKey()->get;

Get project type by key

=head3 Parameters

=over 4

=item B<< projectTypeKey >>

The key of the project type.

=back


Returns a L<< JIRA::API::ProjectType >>.

=cut

sub _build_getProjectTypeByKey_request( $self, %options ) {
    croak "Missing required parameter 'projectTypeKey'"
        unless exists $options{ 'projectTypeKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/type/{projectTypeKey}' );
    my $path = $template->process(
              'projectTypeKey' => delete $options{'projectTypeKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectTypeByKey( $self, %options ) {
    my $tx = $self->_build_getProjectTypeByKey_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectType->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAccessibleProjectTypeByKey >>

  my $res = $client->getAccessibleProjectTypeByKey()->get;

Get accessible project type by key

=head3 Parameters

=over 4

=item B<< projectTypeKey >>

The key of the project type.

=back


Returns a L<< JIRA::API::ProjectType >>.

=cut

sub _build_getAccessibleProjectTypeByKey_request( $self, %options ) {
    croak "Missing required parameter 'projectTypeKey'"
        unless exists $options{ 'projectTypeKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/type/{projectTypeKey}/accessible' );
    my $path = $template->process(
              'projectTypeKey' => delete $options{'projectTypeKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAccessibleProjectTypeByKey( $self, %options ) {
    my $tx = $self->_build_getAccessibleProjectTypeByKey_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectType->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project type is not accessible to the user.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteProject >>

  my $res = $client->deleteProject()->get;

Delete project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< enableUndo >>

Whether this project is placed in the Jira recycle bin where it will be available for restoration.

=back



=cut

sub _build_deleteProject_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'enableUndo' => delete $options{'enableUndo'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteProject( $self, %options ) {
    my $tx = $self->_build_deleteProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the project is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to delete it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProject >>

  my $res = $client->getProject()->get;

Get project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Note that the project description, issue types, and project lead are included in all responses by default. Expand options include:

=over

=item *

C<description> The project description.


=item *

C<issueTypes> The issue types associated with the project.


=item *

C<lead> The project lead.


=item *

C<projectKeys> All project keys associated with the project.


=item *

C<issueTypeHierarchy> The project issue type hierarchy.


=back

=item B<< properties >>

A list of project properties to return for the project. This parameter accepts a comma-separated list.

=back


Returns a L<< JIRA::API::Project >>.

=cut

sub _build_getProject_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'properties' => delete $options{'properties'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProject( $self, %options ) {
    my $tx = $self->_build_getProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Project->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateProject >>

  my $res = $client->updateProject()->get;

Update project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Note that the project description, issue types, and project lead are included in all responses by default. Expand options include:

=over

=item *

C<description> The project description.


=item *

C<issueTypes> The issue types associated with the project.


=item *

C<lead> The project lead.


=item *

C<projectKeys> All project keys associated with the project.


=back

=back


=head3 Options

=over 4

=item C<< assigneeType >>

The default assignee when creating issues for this project.

=item C<< avatarId >>

An integer value for the project's avatar.

=item C<< categoryId >>

The ID of the project's category. A complete list of category IDs is found using the L<Get all project categories|#api-rest-api-3-projectCategory-get> operation. To remove the project category from the project, set the value to C<-1.>

=item C<< description >>

A brief description of the project.

=item C<< issueSecurityScheme >>

The ID of the issue security scheme for the project, which enables you to control who can and cannot view issues. Use the L<Get issue security schemes|#api-rest-api-3-issuesecurityschemes-get> resource to get all issue security scheme IDs.

=item C<< key >>

Project keys must be unique and start with an uppercase letter followed by one or more uppercase alphanumeric characters. The maximum length is 10 characters.

=item C<< lead >>

This parameter is deprecated because of privacy changes. Use C<leadAccountId> instead. See the L<migration guide|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details. The user name of the project lead. Cannot be provided with C<leadAccountId>.

=item C<< leadAccountId >>

The account ID of the project lead. Cannot be provided with C<lead>.

=item C<< name >>

The name of the project.

=item C<< notificationScheme >>

The ID of the notification scheme for the project. Use the L<Get notification schemes|#api-rest-api-3-notificationscheme-get> resource to get a list of notification scheme IDs.

=item C<< permissionScheme >>

The ID of the permission scheme for the project. Use the L<Get all permission schemes|#api-rest-api-3-permissionscheme-get> resource to see a list of all permission scheme IDs.

=item C<< url >>

A link to information about this project, such as project documentation

=back

Returns a L<< JIRA::API::Project >>.

=cut

sub _build_updateProject_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::UpdateProjectDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateProject( $self, %options ) {
    my $tx = $self->_build_updateProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the project is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Project->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if: * the user does not have the necessary permission to update project details. * the permission scheme is being changed and the Jira instance is Jira Core Free or Jira Software Free. Permission schemes cannot be changed on free plans.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< archiveProject >>

  my $res = $client->archiveProject()->get;

Archive project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns a L<<  >>.

=cut

sub _build_archiveProject_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/archive' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub archiveProject( $self, %options ) {
    my $tx = $self->_build_archiveProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateProjectAvatar >>

  my $res = $client->updateProjectAvatar()->get;

Set project avatar

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The ID or (case-sensitive) key of the project.

=back


=head3 Options

=over 4

=item C<< fileName >>

The file name of the avatar icon. Returned for system avatars.

=item C<< id >>

The ID of the avatar.

=item C<< isDeletable >>

Whether the avatar can be deleted.

=item C<< isSelected >>

Whether the avatar is used in Jira. For example, shown as a project's avatar.

=item C<< isSystemAvatar >>

Whether the avatar is a system avatar.

=item C<< owner >>

The owner of the avatar. For a system avatar the owner is null (and nothing is returned). For non-system avatars this is the appropriate identifier, such as the ID for a project or the account ID for a user.

=item C<< urls >>

The list of avatar icon URLs.

=back

Returns a L<<  >>.

=cut

sub _build_updateProjectAvatar_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/avatar' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::Avatar->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateProjectAvatar( $self, %options ) {
    my $tx = $self->_build_updateProjectAvatar_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to administer the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or avatar is not found or the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteProjectAvatar >>

  my $res = $client->deleteProjectAvatar()->get;

Delete project avatar

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or (case-sensitive) key.

=item B<< id >>

The ID of the avatar.

=back



=cut

sub _build_deleteProjectAvatar_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/avatar/{id}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteProjectAvatar( $self, %options ) {
    my $tx = $self->_build_deleteProjectAvatar_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the avatar is a system avatar or the user does not have permission to administer the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or avatar is not found or the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createProjectAvatar >>

  my $res = $client->createProjectAvatar()->get;

Load project avatar

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The ID or (case-sensitive) key of the project.

=item B<< x >>

The X coordinate of the top-left corner of the crop region.

=item B<< y >>

The Y coordinate of the top-left corner of the crop region.

=item B<< size >>

The length of each side of the crop region.

=back


Returns a L<< JIRA::API::Avatar >>.

=cut

sub _build_createProjectAvatar_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/avatar2' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'x' => delete $options{'x'},
        maybe 'y' => delete $options{'y'},
        maybe 'size' => delete $options{'size'},
    );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => '*/*',
        }
        # XXX Need to fill the body
        # => $body,
    );

    return $tx
}


sub createProjectAvatar( $self, %options ) {
    my $tx = $self->_build_createProjectAvatar_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Avatar->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * an image isn't included in the request. * the image type is unsupported. * the crop parameters extend the crop area beyond the edge of the image.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to administer the project or an anonymous call is made to the operation.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllProjectAvatars >>

  my $res = $client->getAllProjectAvatars()->get;

Get all project avatars

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The ID or (case-sensitive) key of the project.

=back


Returns a L<< JIRA::API::ProjectAvatars >>.

=cut

sub _build_getAllProjectAvatars_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/avatars' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllProjectAvatars( $self, %options ) {
    my $tx = $self->_build_getAllProjectAvatars_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectAvatars->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectComponentsPaginated >>

  my $res = $client->getProjectComponentsPaginated()->get;

Get project components paginated

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<description> Sorts by the component description.


=item *

C<issueCount> Sorts by the count of issues associated with the component.


=item *

C<lead> Sorts by the user key of the component's project lead.


=item *

C<name> Sorts by component name.


=back

=item B<< query >>

Filter the results using a literal string. Components with a matching C<name> or C<description> are returned (case insensitive).

=back


Returns a L<< JIRA::API::PageBeanComponentWithIssueCount >>.

=cut

sub _build_getProjectComponentsPaginated_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/component' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'query' => delete $options{'query'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectComponentsPaginated( $self, %options ) {
    my $tx = $self->_build_getProjectComponentsPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanComponentWithIssueCount->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectComponents >>

  my $res = $client->getProjectComponents()->get;

Get project components

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns an array of L<< JIRA::API::ProjectComponent >>.

=cut

sub _build_getProjectComponents_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/components' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectComponents( $self, %options ) {
    my $tx = $self->_build_getProjectComponents_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ProjectComponent->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteProjectAsynchronously >>

  my $res = $client->deleteProjectAsynchronously()->get;

Delete project asynchronously

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns a L<< JIRA::API::TaskProgressBeanObject >>.

=cut

sub _build_deleteProjectAsynchronously_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/delete' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteProjectAsynchronously( $self, %options ) {
    my $tx = $self->_build_deleteProjectAsynchronously_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanObject->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFeaturesForProject >>

  my $res = $client->getFeaturesForProject()->get;

Get project features

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The ID or (case-sensitive) key of the project.

=back


Returns a L<< JIRA::API::ContainerForProjectFeatures >>.

=cut

sub _build_getFeaturesForProject_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/features' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFeaturesForProject( $self, %options ) {
    my $tx = $self->_build_getFeaturesForProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ContainerForProjectFeatures->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< toggleFeatureForProject >>

  my $res = $client->toggleFeatureForProject()->get;

Set project feature state

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The ID or (case-sensitive) key of the project.

=item B<< featureKey >>

The key of the feature.

=back


=head3 Options

=over 4

=item C<< state >>

The feature state.

=back

Returns a L<< JIRA::API::ContainerForProjectFeatures >>.

=cut

sub _build_toggleFeatureForProject_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'featureKey'"
        unless exists $options{ 'featureKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/features/{featureKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'featureKey' => delete $options{'featureKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectFeatureState->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub toggleFeatureForProject( $self, %options ) {
    my $tx = $self->_build_toggleFeatureForProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ContainerForProjectFeatures->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or project feature is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectPropertyKeys >>

  my $res = $client->getProjectPropertyKeys()->get;

Get project property keys

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getProjectPropertyKeys_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/properties' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectPropertyKeys( $self, %options ) {
    my $tx = $self->_build_getProjectPropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteProjectProperty >>

  my $res = $client->deleteProjectProperty()->get;

Delete project property

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< propertyKey >>

The project property key. Use L<Get project property keys|#api-rest-api-3-project-projectIdOrKey-properties-get> to get a list of all project property keys.

=back



=cut

sub _build_deleteProjectProperty_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteProjectProperty( $self, %options ) {
    my $tx = $self->_build_deleteProjectProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the project property is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to administer the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or property is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectProperty >>

  my $res = $client->getProjectProperty()->get;

Get project property

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< propertyKey >>

The project property key. Use L<Get project property keys|#api-rest-api-3-project-projectIdOrKey-properties-get> to get a list of all project property keys.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getProjectProperty_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectProperty( $self, %options ) {
    my $tx = $self->_build_getProjectProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or property is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setProjectProperty >>

  my $res = $client->setProjectProperty()->get;

Set project property

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< propertyKey >>

The key of the project property. The maximum length is 255 characters.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setProjectProperty_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setProjectProperty( $self, %options ) {
    my $tx = $self->_build_setProjectProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the project property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the project property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the project key or id is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to administer the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< restore >>

  my $res = $client->restore()->get;

Restore deleted or archived project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns a L<< JIRA::API::Project >>.

=cut

sub _build_restore_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/restore' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub restore( $self, %options ) {
    my $tx = $self->_build_restore_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Project->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectRoles >>

  my $res = $client->getProjectRoles()->get;

Get project roles for project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns a L<< object >>.

=cut

sub _build_getProjectRoles_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/role' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectRoles( $self, %options ) {
    my $tx = $self->_build_getProjectRoles_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing or if the user lacks administrative permissions for the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or or if the user does not have administrative permissions for the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteActor >>

  my $res = $client->deleteActor()->get;

Delete actors from project role

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=item B<< user >>

The user account ID of the user to remove from the project role.

=item B<< group >>

The name of the group to remove from the project role. This parameter cannot be used with the C<groupId> parameter. As a group's name can change, use of C<groupId> is recommended.

=item B<< groupId >>

The ID of the group to remove from the project role. This parameter cannot be used with the C<group> parameter.

=back



=cut

sub _build_deleteActor_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/role/{id}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'user' => delete $options{'user'},
        maybe 'group' => delete $options{'group'},
        maybe 'groupId' => delete $options{'groupId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteActor( $self, %options ) {
    my $tx = $self->_build_deleteActor_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the project or project role is not found. * the calling user does not have administrative permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectRole >>

  my $res = $client->getProjectRole()->get;

Get project role for project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=item B<< excludeInactiveUsers >>

Exclude inactive users.

=back


Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_getProjectRole_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/role/{id}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'excludeInactiveUsers' => delete $options{'excludeInactiveUsers'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectRole( $self, %options ) {
    my $tx = $self->_build_getProjectRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the project or project role is not found. * the user does not have administrative permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addActorUsers >>

  my $res = $client->addActorUsers()->get;

Add actors to project role

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


=head3 Options

=over 4

=item C<< group >>

The name of the group to add. This parameter cannot be used with the C<groupId> parameter. As a group's name can change, use of C<groupId> is recommended.

=item C<< groupId >>

The ID of the group to add. This parameter cannot be used with the C<group> parameter.

=item C<< user >>

The user account ID of the user to add.

=back

Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_addActorUsers_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/role/{id}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ActorsMap->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addActorUsers( $self, %options ) {
    my $tx = $self->_build_addActorUsers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful. The complete list of actors for the project is returned. For example, the cURL request above adds a group, *jira-developers*. For the response below to be returned as a result of that request, the user *Mia Krystof* would have previously been added as a `user` actor for this project.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing or if the calling user lacks administrative permissions for the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the project is not found. * the user or group is not found. * the group or user is not active.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setActors >>

  my $res = $client->setActors()->get;

Set actors for project role

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


=head3 Options

=over 4

=item C<< categorisedActors >>

The actors to add to the project role.

Add groups using:

=over

=item *

C<atlassian-group-role-actor> and a list of group names.


=item *

C<atlassian-group-role-actor-id> and a list of group IDs.


=back

As a group's name can change, use of C<atlassian-group-role-actor-id> is recommended. For example, C<"atlassian-group-role-actor-id":["eef79f81-0b89-4fca-a736-4be531a10869","77f6ab39-e755-4570-a6ae-2d7a8df0bcb8"]>.

Add users using C<atlassian-user-role-actor> and a list of account IDs. For example, C<"atlassian-user-role-actor":["12345678-9abc-def1-2345-6789abcdef12", "abcdef12-3456-789a-bcde-f123456789ab"]>.

=item C<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back

Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_setActors_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/role/{id}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectRoleActorsUpdateBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setActors( $self, %options ) {
    my $tx = $self->_build_setActors_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful. The complete list of actors for the project is returned.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing or if the calling user lacks administrative permissions for the project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the project is not found. * a user or group is not found. * a group or user is not active.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectRoleDetails >>

  my $res = $client->getProjectRoleDetails()->get;

Get project role details

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< currentMember >>

Whether the roles should be filtered to include only those the user is assigned to.

=item B<< excludeConnectAddons >>

=back


Returns an array of L<< JIRA::API::ProjectRoleDetails >>.

=cut

sub _build_getProjectRoleDetails_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/roledetails' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'currentMember' => delete $options{'currentMember'},
        maybe 'excludeConnectAddons' => delete $options{'excludeConnectAddons'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectRoleDetails( $self, %options ) {
    my $tx = $self->_build_getProjectRoleDetails_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ProjectRoleDetails->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or if the user does not have the necessary permissions for the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllStatuses >>

  my $res = $client->getAllStatuses()->get;

Get all statuses for project

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=back


Returns an array of L<< JIRA::API::IssueTypeWithStatus >>.

=cut

sub _build_getAllStatuses_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/statuses' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllStatuses( $self, %options ) {
    my $tx = $self->_build_getAllStatuses_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::IssueTypeWithStatus->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateProjectType >>

  my $res = $client->updateProjectType()->get;

Update project type

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< newProjectTypeKey >>

The key of the new project type.

=back


Returns a L<< JIRA::API::Project >>.

=cut

sub _build_updateProjectType_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };
    croak "Missing required parameter 'newProjectTypeKey'"
        unless exists $options{ 'newProjectTypeKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/type/{newProjectTypeKey}' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
              'newProjectTypeKey' => delete $options{'newProjectTypeKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub updateProjectType( $self, %options ) {
    my $tx = $self->_build_updateProjectType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the project type is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Project->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectVersionsPaginated >>

  my $res = $client->getProjectVersionsPaginated()->get;

Get project versions paginated

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<description> Sorts by version description.


=item *

C<name> Sorts by version name.


=item *

C<releaseDate> Sorts by release date, starting with the oldest date. Versions with no release date are listed last.


=item *

C<sequence> Sorts by the order of appearance in the user interface.


=item *

C<startDate> Sorts by start date, starting with the oldest date. Versions with no start date are listed last.


=back

=item B<< query >>

Filter the results using a literal string. Versions with matching C<name> or C<description> are returned (case insensitive).

=item B<< status >>

A list of status values used to filter the results by version status. This parameter accepts a comma-separated list. The status values are C<released>, C<unreleased>, and C<archived>.

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<issuesstatus> Returns the number of issues in each status category for each version.


=item *

C<operations> Returns actions that can be performed on the specified version.


=back

=back


Returns a L<< JIRA::API::PageBeanVersion >>.

=cut

sub _build_getProjectVersionsPaginated_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/version' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'query' => delete $options{'query'},
        maybe 'status' => delete $options{'status'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectVersionsPaginated( $self, %options ) {
    my $tx = $self->_build_getProjectVersionsPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanVersion->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectVersions >>

  my $res = $client->getProjectVersions()->get;

Get project versions

=head3 Parameters

=over 4

=item B<< projectIdOrKey >>

The project ID or project key (case sensitive).

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts C<operations>, which returns actions that can be performed on the version.

=back


Returns an array of L<< JIRA::API::Version >>.

=cut

sub _build_getProjectVersions_request( $self, %options ) {
    croak "Missing required parameter 'projectIdOrKey'"
        unless exists $options{ 'projectIdOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectIdOrKey}/versions' );
    my $path = $template->process(
              'projectIdOrKey' => delete $options{'projectIdOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectVersions( $self, %options ) {
    my $tx = $self->_build_getProjectVersions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Version->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectEmail >>

  my $res = $client->getProjectEmail()->get;

Get project's sender email

=head3 Parameters

=over 4

=item B<< projectId >>

The project ID.

=back


Returns a L<< JIRA::API::ProjectEmailAddress >>.

=cut

sub _build_getProjectEmail_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectId}/email' );
    my $path = $template->process(
              'projectId' => delete $options{'projectId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectEmail( $self, %options ) {
    my $tx = $self->_build_getProjectEmail_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectEmailAddress->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to read project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or project's sender email address is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateProjectEmail >>

  my $res = $client->updateProjectEmail()->get;

Set project's sender email

=head3 Parameters

=over 4

=item B<< projectId >>

The project ID.

=back


=head3 Options

=over 4

=item C<< emailAddress >>

The email address.

=item C<< emailAddressStatus >>

When using a custom domain, the status of the email address.

=back

Returns a L<<  >>.

=cut

sub _build_updateProjectEmail_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectId}/email' );
    my $path = $template->process(
              'projectId' => delete $options{'projectId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectEmailAddress->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateProjectEmail( $self, %options ) {
    my $tx = $self->_build_updateProjectEmail_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the project's sender email address is successfully set.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid, if the email address is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to read project.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getHierarchy >>

  my $res = $client->getHierarchy()->get;

Get project issue type hierarchy

=head3 Parameters

=over 4

=item B<< projectId >>

The ID of the project.

=back


Returns a L<< JIRA::API::ProjectIssueTypeHierarchy >>.

=cut

sub _build_getHierarchy_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectId}/hierarchy' );
    my $path = $template->process(
              'projectId' => delete $options{'projectId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getHierarchy( $self, %options ) {
    my $tx = $self->_build_getHierarchy_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectIssueTypeHierarchy->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectIssueSecurityScheme >>

  my $res = $client->getProjectIssueSecurityScheme()->get;

Get project issue security scheme

=head3 Parameters

=over 4

=item B<< projectKeyOrId >>

The project ID or project key (case sensitive).

=back


Returns a L<< JIRA::API::SecurityScheme >>.

=cut

sub _build_getProjectIssueSecurityScheme_request( $self, %options ) {
    croak "Missing required parameter 'projectKeyOrId'"
        unless exists $options{ 'projectKeyOrId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectKeyOrId}/issuesecuritylevelscheme' );
    my $path = $template->process(
              'projectKeyOrId' => delete $options{'projectKeyOrId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectIssueSecurityScheme( $self, %options ) {
    my $tx = $self->_build_getProjectIssueSecurityScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SecurityScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the project is visible to the user but the user doesn't have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getNotificationSchemeForProject >>

  my $res = $client->getNotificationSchemeForProject()->get;

Get project notification scheme

=head3 Parameters

=over 4

=item B<< projectKeyOrId >>

The project ID or project key (case sensitive).

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<all> Returns all expandable information


=item *

C<field> Returns information about any custom fields assigned to receive an event


=item *

C<group> Returns information about any groups assigned to receive an event


=item *

C<notificationSchemeEvents> Returns a list of event associations. This list is returned for all expandable information


=item *

C<projectRole> Returns information about any project roles assigned to receive an event


=item *

C<user> Returns information about any users assigned to receive an event


=back

=back


Returns a L<< JIRA::API::NotificationScheme >>.

=cut

sub _build_getNotificationSchemeForProject_request( $self, %options ) {
    croak "Missing required parameter 'projectKeyOrId'"
        unless exists $options{ 'projectKeyOrId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectKeyOrId}/notificationscheme' );
    my $path = $template->process(
              'projectKeyOrId' => delete $options{'projectKeyOrId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getNotificationSchemeForProject( $self, %options ) {
    my $tx = $self->_build_getNotificationSchemeForProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::NotificationScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user is not an administrator.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAssignedPermissionScheme >>

  my $res = $client->getAssignedPermissionScheme()->get;

Get assigned permission scheme

=head3 Parameters

=over 4

=item B<< projectKeyOrId >>

The project ID or project key (case sensitive).

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


Returns a L<< JIRA::API::PermissionScheme >>.

=cut

sub _build_getAssignedPermissionScheme_request( $self, %options ) {
    croak "Missing required parameter 'projectKeyOrId'"
        unless exists $options{ 'projectKeyOrId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectKeyOrId}/permissionscheme' );
    my $path = $template->process(
              'projectKeyOrId' => delete $options{'projectKeyOrId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAssignedPermissionScheme( $self, %options ) {
    my $tx = $self->_build_getAssignedPermissionScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to view the project's configuration.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view the project.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignPermissionScheme >>

  my $res = $client->assignPermissionScheme()->get;

Assign permission scheme

=head3 Parameters

=over 4

=item B<< projectKeyOrId >>

The project ID or project key (case sensitive).

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Note that permissions are included when you specify any value. Expand options include:

=over

=item *

C<all> Returns all expandable information.


=item *

C<field> Returns information about the custom field granted the permission.


=item *

C<group> Returns information about the group that is granted the permission.


=item *

C<permissions> Returns all permission grants for each permission scheme.


=item *

C<projectRole> Returns information about the project role granted the permission.


=item *

C<user> Returns information about the user who is granted the permission.


=back

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the permission scheme to associate with the project. Use the L<Get all permission schemes|#api-rest-api-3-permissionscheme-get> resource to get a list of permission scheme IDs.

=back

Returns a L<< JIRA::API::PermissionScheme >>.

=cut

sub _build_assignPermissionScheme_request( $self, %options ) {
    croak "Missing required parameter 'projectKeyOrId'"
        unless exists $options{ 'projectKeyOrId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/project/{projectKeyOrId}/permissionscheme' );
    my $path = $template->process(
              'projectKeyOrId' => delete $options{'projectKeyOrId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::IdBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignPermissionScheme( $self, %options ) {
    my $tx = $self->_build_assignPermissionScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PermissionScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if: * the user does not have the necessary permission to edit the project's configuration. * the Jira instance is Jira Core Free or Jira Software Free. Permission schemes cannot be assigned to projects on free plans.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project or permission scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getSecurityLevelsForProject >>

  my $res = $client->getSecurityLevelsForProject()->get;

Get project issue security levels

=head3 Parameters

=over 4

=item B<< projectKeyOrId >>

The project ID or project key (case sensitive).

=back


Returns a L<< JIRA::API::ProjectIssueSecurityLevels >>.

=cut

sub _build_getSecurityLevelsForProject_request( $self, %options ) {
    croak "Missing required parameter 'projectKeyOrId'"
        unless exists $options{ 'projectKeyOrId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/project/{projectKeyOrId}/securitylevel' );
    my $path = $template->process(
              'projectKeyOrId' => delete $options{'projectKeyOrId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getSecurityLevelsForProject( $self, %options ) {
    my $tx = $self->_build_getSecurityLevelsForProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectIssueSecurityLevels->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the project is not found or the user does not have permission to view it.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllProjectCategories >>

  my $res = $client->getAllProjectCategories()->get;

Get all project categories

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ProjectCategory >>.

=cut

sub _build_getAllProjectCategories_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/projectCategory';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllProjectCategories( $self, %options ) {
    my $tx = $self->_build_getAllProjectCategories_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ProjectCategory->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createProjectCategory >>

  my $res = $client->createProjectCategory()->get;

Create project category

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the project category.

=item C<< id >>

The ID of the project category.

=item C<< name >>

The name of the project category. Required on create, optional on update.

=item C<< self >>

The URL of the project category.

=back

Returns a L<< JIRA::API::ProjectCategory >>.

=cut

sub _build_createProjectCategory_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/projectCategory';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectCategory->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createProjectCategory( $self, %options ) {
    my $tx = $self->_build_createProjectCategory_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectCategory->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `name` is not provided or exceeds 255 characters. * `description` exceeds 1000 characters.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the project category name is in use.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeProjectCategory >>

  my $res = $client->removeProjectCategory()->get;

Delete project category

=head3 Parameters

=over 4

=item B<< id >>

ID of the project category to delete.

=back



=cut

sub _build_removeProjectCategory_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/projectCategory/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeProjectCategory( $self, %options ) {
    my $tx = $self->_build_removeProjectCategory_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project category is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectCategoryById >>

  my $res = $client->getProjectCategoryById()->get;

Get project category by ID

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project category.

=back


Returns a L<< JIRA::API::ProjectCategory >>.

=cut

sub _build_getProjectCategoryById_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/projectCategory/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectCategoryById( $self, %options ) {
    my $tx = $self->_build_getProjectCategoryById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectCategory->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project category is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateProjectCategory >>

  my $res = $client->updateProjectCategory()->get;

Update project category

=head3 Parameters

=over 4

=item B<< id >>

=back


=head3 Options

=over 4

=item C<< description >>

The description of the project category.

=item C<< id >>

The ID of the project category.

=item C<< name >>

The name of the project category. Required on create, optional on update.

=item C<< self >>

The URL of the project category.

=back

Returns a L<< JIRA::API::UpdatedProjectCategory >>.

=cut

sub _build_updateProjectCategory_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/projectCategory/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ProjectCategory->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateProjectCategory( $self, %options ) {
    my $tx = $self->_build_updateProjectCategory_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::UpdatedProjectCategory->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `name` has been modified and exceeds 255 characters. * `description` has been modified and exceeds 1000 characters.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project category is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< validateProjectKey >>

  my $res = $client->validateProjectKey()->get;

Validate project key

=head3 Parameters

=over 4

=item B<< key >>

The project key.

=back


Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_validateProjectKey_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/projectvalidate/key';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub validateProjectKey( $self, %options ) {
    my $tx = $self->_build_validateProjectKey_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getValidProjectKey >>

  my $res = $client->getValidProjectKey()->get;

Get valid project key

=head3 Parameters

=over 4

=item B<< key >>

The project key.

=back


Returns a L<< string >>.

=cut

sub _build_getValidProjectKey_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/projectvalidate/validProjectKey';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getValidProjectKey( $self, %options ) {
    my $tx = $self->_build_getValidProjectKey_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getValidProjectName >>

  my $res = $client->getValidProjectName()->get;

Get valid project name

=head3 Parameters

=over 4

=item B<< name >>

The project name.

=back


Returns a L<< string >>.

=cut

sub _build_getValidProjectName_request( $self, %options ) {
    croak "Missing required parameter 'name'"
        unless exists $options{ 'name' };

    my $method = 'GET';
    my $path = '/rest/api/3/projectvalidate/validProjectName';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'name' => delete $options{'name'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getValidProjectName( $self, %options ) {
    my $tx = $self->_build_getValidProjectName_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if a valid project name cannot be generated.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getResolutions >>

  my $res = $client->getResolutions()->get;

Get resolutions

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::Resolution >>.

=cut

sub _build_getResolutions_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/resolution';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getResolutions( $self, %options ) {
    my $tx = $self->_build_getResolutions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Resolution->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createResolution >>

  my $res = $client->createResolution()->get;

Create resolution

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the resolution.

=item C<< name >>

The name of the resolution. Must be unique (case-insensitive).

=back

Returns a L<< JIRA::API::ResolutionId >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_createResolution_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/resolution';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateResolutionDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createResolution( $self, %options ) {
    my $tx = $self->_build_createResolution_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ResolutionId->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setDefaultResolution >>

  my $res = $client->setDefaultResolution()->get;

Set default resolution

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the new default issue resolution. Must be an existing ID or null. Setting this to null erases the default resolution setting.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_setDefaultResolution_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/resolution/default';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::SetDefaultResolutionRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setDefaultResolution( $self, %options ) {
    my $tx = $self->_build_setDefaultResolution_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue resolution isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< moveResolutions >>

  my $res = $client->moveResolutions()->get;

Move resolutions

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< after >>

The ID of the resolution. Required if C<position> isn't provided.

=item C<< ids >>

The list of resolution IDs to be reordered. Cannot contain duplicates nor after ID.

=item C<< position >>

The position for issue resolutions to be moved to. Required if C<after> isn't provided.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_moveResolutions_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/resolution/move';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ReorderIssueResolutionsRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub moveResolutions( $self, %options ) {
    my $tx = $self->_build_moveResolutions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue resolution isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< searchResolutions >>

  my $res = $client->searchResolutions()->get;

Search resolutions

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of resolutions IDs to be filtered out

=item B<< onlyDefault >>

When set to true, return default only, when IDs provided, if none of them is default, return empty page. Default value is false

=back


Returns a L<< JIRA::API::PageBeanResolutionJsonBean >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_searchResolutions_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/resolution/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'onlyDefault' => delete $options{'onlyDefault'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub searchResolutions( $self, %options ) {
    my $tx = $self->_build_searchResolutions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanResolutionJsonBean->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteResolution >>

  my $res = $client->deleteResolution()->get;

Delete resolution

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue resolution.

=item B<< replaceWith >>

The ID of the issue resolution that will replace the currently selected resolution.

=back


Returns a L<< JIRA::API::TaskProgressBeanObject >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deleteResolution_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'replaceWith'"
        unless exists $options{ 'replaceWith' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/resolution/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'replaceWith' => delete $options{'replaceWith'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteResolution( $self, %options ) {
    my $tx = $self->_build_deleteResolution_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 303 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanObject->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue resolution isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 409 ) {
            # Returned if a task to delete the issue resolution is already running.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getResolution >>

  my $res = $client->getResolution()->get;

Get resolution

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue resolution value.

=back


Returns a L<< JIRA::API::Resolution >>.

=cut

sub _build_getResolution_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/resolution/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getResolution( $self, %options ) {
    my $tx = $self->_build_getResolution_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Resolution->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue resolution value is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateResolution >>

  my $res = $client->updateResolution()->get;

Update resolution

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue resolution.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the resolution.

=item C<< name >>

The name of the resolution. Must be unique.

=back

Returns a L<<  >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_updateResolution_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/resolution/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateResolutionDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateResolution( $self, %options ) {
    my $tx = $self->_build_updateResolution_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request isn't valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the issue resolution isn't found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllProjectRoles >>

  my $res = $client->getAllProjectRoles()->get;

Get all project roles

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ProjectRole >>.

=cut

sub _build_getAllProjectRoles_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/role';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllProjectRoles( $self, %options ) {
    my $tx = $self->_build_getAllProjectRoles_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ProjectRole->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createProjectRole >>

  my $res = $client->createProjectRole()->get;

Create project role

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

A description of the project role. Required when fully updating a project role. Optional when creating or partially updating a project role.

=item C<< name >>

The name of the project role. Must be unique. Cannot begin or end with whitespace. The maximum length is 255 characters. Required when creating a project role. Optional when partially updating a project role.

=back

Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_createProjectRole_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/role';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateUpdateRoleRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createProjectRole( $self, %options ) {
    my $tx = $self->_build_createProjectRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid. The `name` cannot be empty or start or end with whitespace.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if a project role with the provided name already exists.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteProjectRole >>

  my $res = $client->deleteProjectRole()->get;

Delete project role

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role to delete. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=item B<< swap >>

The ID of the project role that will replace the one being deleted.

=back



=cut

sub _build_deleteProjectRole_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/role/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'swap' => delete $options{'swap'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteProjectRole( $self, %options ) {
    my $tx = $self->_build_deleteProjectRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid or if the replacement project role is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role being deleted is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the project role being deleted is in use and a replacement project role is not specified in the request.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectRoleById >>

  my $res = $client->getProjectRoleById()->get;

Get project role by ID

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_getProjectRoleById_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/role/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectRoleById( $self, %options ) {
    my $tx = $self->_build_getProjectRoleById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< partialUpdateProjectRole >>

  my $res = $client->partialUpdateProjectRole()->get;

Partial update project role

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


=head3 Options

=over 4

=item C<< description >>

A description of the project role. Required when fully updating a project role. Optional when creating or partially updating a project role.

=item C<< name >>

The name of the project role. Must be unique. Cannot begin or end with whitespace. The maximum length is 255 characters. Required when creating a project role. Optional when partially updating a project role.

=back

Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_partialUpdateProjectRole_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/role/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateUpdateRoleRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub partialUpdateProjectRole( $self, %options ) {
    my $tx = $self->_build_partialUpdateProjectRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< fullyUpdateProjectRole >>

  my $res = $client->fullyUpdateProjectRole()->get;

Fully update project role

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


=head3 Options

=over 4

=item C<< description >>

A description of the project role. Required when fully updating a project role. Optional when creating or partially updating a project role.

=item C<< name >>

The name of the project role. Must be unique. Cannot begin or end with whitespace. The maximum length is 255 characters. Required when creating a project role. Optional when partially updating a project role.

=back

Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_fullyUpdateProjectRole_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/role/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateUpdateRoleRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub fullyUpdateProjectRole( $self, %options ) {
    my $tx = $self->_build_fullyUpdateProjectRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid. The `name` cannot be empty or start or end with whitespace.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteProjectRoleActorsFromRole >>

  my $res = $client->deleteProjectRoleActorsFromRole()->get;

Delete default actors from project role

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=item B<< user >>

The user account ID of the user to remove as a default actor.

=item B<< groupId >>

The group ID of the group to be removed as a default actor. This parameter cannot be used with the C<group> parameter.

=item B<< group >>

The group name of the group to be removed as a default actor.This parameter cannot be used with the C<groupId> parameter. As a group's name can change, use of C<groupId> is recommended.

=back


Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_deleteProjectRoleActorsFromRole_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/role/{id}/actors' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'user' => delete $options{'user'},
        maybe 'groupId' => delete $options{'groupId'},
        maybe 'group' => delete $options{'group'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteProjectRoleActorsFromRole( $self, %options ) {
    my $tx = $self->_build_deleteProjectRoleActorsFromRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getProjectRoleActorsForRole >>

  my $res = $client->getProjectRoleActorsForRole()->get;

Get default actors for project role

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_getProjectRoleActorsForRole_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/role/{id}/actors' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getProjectRoleActorsForRole( $self, %options ) {
    my $tx = $self->_build_getProjectRoleActorsForRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addProjectRoleActorsToRole >>

  my $res = $client->addProjectRoleActorsToRole()->get;

Add default actors to project role

=head3 Parameters

=over 4

=item B<< id >>

The ID of the project role. Use L<Get all project roles|#api-rest-api-3-role-get> to get a list of project role IDs.

=back


=head3 Options

=over 4

=item C<< group >>

The name of the group to add as a default actor. This parameter cannot be used with the C<groupId> parameter. As a group's name can change,use of C<groupId> is recommended. This parameter accepts a comma-separated list. For example, C<"group":["project-admin", "jira-developers"]>.

=item C<< groupId >>

The ID of the group to add as a default actor. This parameter cannot be used with the C<group> parameter This parameter accepts a comma-separated list. For example, C<"groupId":["77f6ab39-e755-4570-a6ae-2d7a8df0bcb8", "0c011f85-69ed-49c4-a801-3b18d0f771bc"]>.

=item C<< user >>

The account IDs of the users to add as default actors. This parameter accepts a comma-separated list. For example, C<"user":["5b10a2844c20165700ede21g", "5b109f2e9729b51b54dc274d"]>.

=back

Returns a L<< JIRA::API::ProjectRole >>.

=cut

sub _build_addProjectRoleActorsToRole_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/role/{id}/actors' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ActorInputBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addProjectRoleActorsToRole( $self, %options ) {
    my $tx = $self->_build_addProjectRoleActorsToRole_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ProjectRole->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have administrative permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project role is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getScreens >>

  my $res = $client->getScreens()->get;

Get screens

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of screen IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>.

=item B<< queryString >>

String used to perform a case-insensitive partial match with screen name.

=item B<< scope >>

The scope filter string. To filter by multiple scope, provide an ampersand-separated list. For example, C<scope=GLOBAL&scope=PROJECT>.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<id> Sorts by screen ID.


=item *

C<name> Sorts by screen name.


=back

=back


Returns a L<< JIRA::API::PageBeanScreen >>.

=cut

sub _build_getScreens_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/screens';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'queryString' => delete $options{'queryString'},
        maybe 'scope' => delete $options{'scope'},
        maybe 'orderBy' => delete $options{'orderBy'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getScreens( $self, %options ) {
    my $tx = $self->_build_getScreens_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanScreen->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createScreen >>

  my $res = $client->createScreen()->get;

Create screen

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the screen. The maximum length is 255 characters.

=item C<< name >>

The name of the screen. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::Screen >>.

=cut

sub _build_createScreen_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/screens';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ScreenDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createScreen( $self, %options ) {
    my $tx = $self->_build_createScreen_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Screen->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addFieldToDefaultScreen >>

  my $res = $client->addFieldToDefaultScreen()->get;

Add field to default screen

=head3 Parameters

=over 4

=item B<< fieldId >>

The ID of the field.

=back


Returns a L<<  >>.

=cut

sub _build_addFieldToDefaultScreen_request( $self, %options ) {
    croak "Missing required parameter 'fieldId'"
        unless exists $options{ 'fieldId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/screens/addToDefault/{fieldId}' );
    my $path = $template->process(
              'fieldId' => delete $options{'fieldId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub addFieldToDefaultScreen( $self, %options ) {
    my $tx = $self->_build_addFieldToDefaultScreen_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the field it not found or the field is already present.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteScreen >>

  my $res = $client->deleteScreen()->get;

Delete screen

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=back



=cut

sub _build_deleteScreen_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteScreen( $self, %options ) {
    my $tx = $self->_build_deleteScreen_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the screen is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateScreen >>

  my $res = $client->updateScreen()->get;

Update screen

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the screen. The maximum length is 255 characters.

=item C<< name >>

The name of the screen. The name must be unique. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::Screen >>.

=cut

sub _build_updateScreen_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateScreenDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateScreen( $self, %options ) {
    my $tx = $self->_build_updateScreen_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Screen->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the screen is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAvailableScreenFields >>

  my $res = $client->getAvailableScreenFields()->get;

Get available screen fields

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=back


Returns an array of L<< JIRA::API::ScreenableField >>.

=cut

sub _build_getAvailableScreenFields_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/availableFields' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAvailableScreenFields( $self, %options ) {
    my $tx = $self->_build_getAvailableScreenFields_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ScreenableField->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllScreenTabs >>

  my $res = $client->getAllScreenTabs()->get;

Get all screen tabs

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< projectKey >>

The key of the project.

=back


Returns an array of L<< JIRA::API::ScreenableTab >>.

=cut

sub _build_getAllScreenTabs_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'projectKey' => delete $options{'projectKey'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllScreenTabs( $self, %options ) {
    my $tx = $self->_build_getAllScreenTabs_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ScreenableTab->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the screen ID is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addScreenTab >>

  my $res = $client->addScreenTab()->get;

Create screen tab

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the screen tab.

=item C<< name >>

The name of the screen tab. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::ScreenableTab >>.

=cut

sub _build_addScreenTab_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ScreenableTab->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addScreenTab( $self, %options ) {
    my $tx = $self->_build_addScreenTab_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ScreenableTab->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteScreenTab >>

  my $res = $client->deleteScreenTab()->get;

Delete screen tab

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=back



=cut

sub _build_deleteScreenTab_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteScreenTab( $self, %options ) {
    my $tx = $self->_build_deleteScreenTab_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen or screen tab is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< renameScreenTab >>

  my $res = $client->renameScreenTab()->get;

Update screen tab

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the screen tab.

=item C<< name >>

The name of the screen tab. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::ScreenableTab >>.

=cut

sub _build_renameScreenTab_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ScreenableTab->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub renameScreenTab( $self, %options ) {
    my $tx = $self->_build_renameScreenTab_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ScreenableTab->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen or screen tab is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllScreenTabFields >>

  my $res = $client->getAllScreenTabFields()->get;

Get all screen tab fields

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=item B<< projectKey >>

The key of the project.

=back


Returns an array of L<< JIRA::API::ScreenableField >>.

=cut

sub _build_getAllScreenTabFields_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}/fields' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'projectKey' => delete $options{'projectKey'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllScreenTabFields( $self, %options ) {
    my $tx = $self->_build_getAllScreenTabFields_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ScreenableField->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen or screen tab is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< addScreenTabField >>

  my $res = $client->addScreenTabField()->get;

Add screen tab field

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=back


=head3 Options

=over 4

=item C<< fieldId >>

The ID of the field to add.

=back

Returns a L<< JIRA::API::ScreenableField >>.

=cut

sub _build_addScreenTabField_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}/fields' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::AddFieldBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub addScreenTabField( $self, %options ) {
    my $tx = $self->_build_addScreenTabField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ScreenableField->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen, screen tab, or field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeScreenTabField >>

  my $res = $client->removeScreenTabField()->get;

Remove screen tab field

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=item B<< id >>

The ID of the field.

=back



=cut

sub _build_removeScreenTabField_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}/fields/{id}' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeScreenTabField( $self, %options ) {
    my $tx = $self->_build_removeScreenTabField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen, screen tab, or field is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< moveScreenTabField >>

  my $res = $client->moveScreenTabField()->get;

Move screen tab field

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=item B<< id >>

The ID of the field.

=back


=head3 Options

=over 4

=item C<< after >>

The ID of the screen tab field after which to place the moved screen tab field. Required if C<position> isn't provided.

=item C<< position >>

The named position to which the screen tab field should be moved. Required if C<after> isn't provided.

=back

Returns a L<<  >>.

=cut

sub _build_moveScreenTabField_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}/fields/{id}/move' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::MoveFieldBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub moveScreenTabField( $self, %options ) {
    my $tx = $self->_build_moveScreenTabField_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen, screen tab, or field is not found or the field can't be moved to the requested position.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< moveScreenTab >>

  my $res = $client->moveScreenTab()->get;

Move screen tab

=head3 Parameters

=over 4

=item B<< screenId >>

The ID of the screen.

=item B<< tabId >>

The ID of the screen tab.

=item B<< pos >>

The position of tab. The base index is 0.

=back


Returns a L<<  >>.

=cut

sub _build_moveScreenTab_request( $self, %options ) {
    croak "Missing required parameter 'screenId'"
        unless exists $options{ 'screenId' };
    croak "Missing required parameter 'tabId'"
        unless exists $options{ 'tabId' };
    croak "Missing required parameter 'pos'"
        unless exists $options{ 'pos' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/screens/{screenId}/tabs/{tabId}/move/{pos}' );
    my $path = $template->process(
              'screenId' => delete $options{'screenId'},
              'tabId' => delete $options{'tabId'},
              'pos' => delete $options{'pos'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub moveScreenTab( $self, %options ) {
    my $tx = $self->_build_moveScreenTab_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the screen or screen tab is not found or the position is invalid.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getScreenSchemes >>

  my $res = $client->getScreenSchemes()->get;

Get screen schemes

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< id >>

The list of screen scheme IDs. To include multiple IDs, provide an ampersand-separated list. For example, C<id=10000&id=10001>.

=item B<< expand >>

Use L<expand|#expansion> include additional information in the response. This parameter accepts C<issueTypeScreenSchemes> that, for each screen schemes, returns information about the issue type screen scheme the screen scheme is assigned to.

=item B<< queryString >>

String used to perform a case-insensitive partial match with screen scheme name.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<id> Sorts by screen scheme ID.


=item *

C<name> Sorts by screen scheme name.


=back

=back


Returns a L<< JIRA::API::PageBeanScreenScheme >>.

=cut

sub _build_getScreenSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/screenscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'id' => delete $options{'id'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'queryString' => delete $options{'queryString'},
        maybe 'orderBy' => delete $options{'orderBy'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getScreenSchemes( $self, %options ) {
    my $tx = $self->_build_getScreenSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanScreenScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createScreenScheme >>

  my $res = $client->createScreenScheme()->get;

Create screen scheme

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the screen scheme. The maximum length is 255 characters.

=item C<< name >>

The name of the screen scheme. The name must be unique. The maximum length is 255 characters.

=item C<< screens >>

The IDs of the screens for the screen types of the screen scheme. Only screens used in classic projects are accepted.

=back

Returns a L<< JIRA::API::ScreenSchemeId >>.

=cut

sub _build_createScreenScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/screenscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ScreenSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createScreenScheme( $self, %options ) {
    my $tx = $self->_build_createScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ScreenSchemeId->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if a screen used as one of the screen types in the screen scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteScreenScheme >>

  my $res = $client->deleteScreenScheme()->get;

Delete screen scheme

=head3 Parameters

=over 4

=item B<< screenSchemeId >>

The ID of the screen scheme.

=back



=cut

sub _build_deleteScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'screenSchemeId'"
        unless exists $options{ 'screenSchemeId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/screenscheme/{screenSchemeId}' );
    my $path = $template->process(
              'screenSchemeId' => delete $options{'screenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteScreenScheme( $self, %options ) {
    my $tx = $self->_build_deleteScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the screen scheme is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the screen scheme is used in an issue type screen scheme.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the screen scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateScreenScheme >>

  my $res = $client->updateScreenScheme()->get;

Update screen scheme

=head3 Parameters

=over 4

=item B<< screenSchemeId >>

The ID of the screen scheme.

=back


=head3 Options

=over 4

=item C<< description >>

The description of the screen scheme. The maximum length is 255 characters.

=item C<< name >>

The name of the screen scheme. The name must be unique. The maximum length is 255 characters.

=item C<< screens >>

The IDs of the screens for the screen types of the screen scheme. Only screens used in classic projects are accepted.

=back

Returns a L<<  >>.

=cut

sub _build_updateScreenScheme_request( $self, %options ) {
    croak "Missing required parameter 'screenSchemeId'"
        unless exists $options{ 'screenSchemeId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/screenscheme/{screenSchemeId}' );
    my $path = $template->process(
              'screenSchemeId' => delete $options{'screenSchemeId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateScreenSchemeDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateScreenScheme( $self, %options ) {
    my $tx = $self->_build_updateScreenScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the screen scheme or a screen used as one of the screen types is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< searchForIssuesUsingJql >>

  my $res = $client->searchForIssuesUsingJql()->get;

Search for issues using JQL (GET)

=head3 Parameters

=over 4

=item B<< jql >>

The L<JQL|https://confluence.atlassian.com/x/egORLQ> that defines the search. Note:

=over

=item *

If no JQL expression is provided, all issues are returned.


=item *

C<username> and C<userkey> cannot be used as search terms due to privacy reasons. Use C<accountId> instead.


=item *

If a user has hidden their email address in their user profile, partial matches of the email address will not find the user. An exact match is required.


=back

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page. To manage page size, Jira may return fewer items per page where a large number of fields are requested. The greatest number of items returned per page is achieved when requesting C<id> or C<key> only.

=item B<< validateQuery >>

Determines how to validate the JQL query and treat the validation results. Supported values are:

=over

=item *

C<strict> Returns a 400 response code if any errors are found, along with a list of all errors (and warnings).


=item *

C<warn> Returns all errors as warnings.


=item *

C<none> No validation is performed.


=item *

C<true> I<Deprecated> A legacy synonym for C<strict>.


=item *

C<false> I<Deprecated> A legacy synonym for C<warn>.


=back

Note: If the JQL is not correctly formed a 400 response code is returned, regardless of the C<validateQuery> value.

=item B<< fields >>

A list of fields to return for each issue, use it to retrieve a subset of fields. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<*all> Returns all fields.


=item *

C<*navigable> Returns navigable fields.


=item *

Any issue field, prefixed with a minus to exclude.


=back

Examples:

=over

=item *

C<summary,comment> Returns only the summary and comments fields.


=item *

C<-description> Returns all navigable (default) fields except description.


=item *

C<*all,-comment> Returns all fields except comments.


=back

This parameter may be specified multiple times. For example, C<fields=field1,field2&fields=field3>.

Note: All navigable fields are returned by default. This differs from L<GET issue|#api-rest-api-3-issue-issueIdOrKey-get> where the default is all fields.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about issues in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<renderedFields> Returns field values rendered in HTML format.


=item *

C<names> Returns the display name of each field.


=item *

C<schema> Returns the schema describing a field type.


=item *

C<transitions> Returns all possible transitions for the issue.


=item *

C<operations> Returns all possible operations for the issue.


=item *

C<editmeta> Returns information about how each field can be edited.


=item *

C<changelog> Returns a list of recent updates to an issue, sorted by date, starting from the most recent.


=item *

C<versionedRepresentations> Instead of C<fields>, returns C<versionedRepresentations> a JSON array containing each version of a field's value, with the highest numbered item representing the most recent version.


=back

=item B<< properties >>

A list of issue property keys for issue properties to include in the results. This parameter accepts a comma-separated list. Multiple properties can also be provided using an ampersand separated list. For example, C<properties=prop1,prop2&properties=prop3>. A maximum of 5 issue property keys can be specified.

=item B<< fieldsByKeys >>

Reference fields by their key (rather than ID).

=back


Returns a L<< JIRA::API::SearchResults >>.

=cut

sub _build_searchForIssuesUsingJql_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'jql' => delete $options{'jql'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'validateQuery' => delete $options{'validateQuery'},
        maybe 'fields' => delete $options{'fields'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'properties' => delete $options{'properties'},
        maybe 'fieldsByKeys' => delete $options{'fieldsByKeys'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub searchForIssuesUsingJql( $self, %options ) {
    my $tx = $self->_build_searchForIssuesUsingJql_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SearchResults->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the JQL query is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< searchForIssuesUsingJqlPost >>

  my $res = $client->searchForIssuesUsingJqlPost()->get;

Search for issues using JQL (POST)

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< expand >>

Use L<expand|em>#expansion> to include additional information about issues in the response. Note that, unlike the majority of instances where C<expand> is specified, C<expand> is defined as a list of values. The expand options are:

=over

=item *

C<renderedFields> Returns field values rendered in HTML format.


=item *

C<names> Returns the display name of each field.


=item *

C<schema> Returns the schema describing a field type.


=item *

C<transitions> Returns all possible transitions for the issue.


=item *

C<operations> Returns all possible operations for the issue.


=item *

C<editmeta> Returns information about how each field can be edited.


=item *

C<changelog> Returns a list of recent updates to an issue, sorted by date, starting from the most recent.


=item *

C<versionedRepresentations> Instead of C<fields>, returns C<versionedRepresentations> a JSON array containing each version of a field's value, with the highest numbered item representing the most recent version.


=back

=item C<< fields >>

A list of fields to return for each issue, use it to retrieve a subset of fields. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<*all> Returns all fields.


=item *

C<*navigable> Returns navigable fields.


=item *

Any issue field, prefixed with a minus to exclude.


=back

The default is C<*navigable>.

Examples:

=over

=item *

C<summary,comment> Returns the summary and comments fields only.


=item *

C<-description> Returns all navigable (default) fields except description.


=item *

C<*all,-comment> Returns all fields except comments.


=back

Multiple C<fields> parameters can be included in a request.

Note: All navigable fields are returned by default. This differs from L<GET issue|#api-rest-api-3-issue-issueIdOrKey-get> where the default is all fields.

=item C<< fieldsByKeys >>

Reference fields by their key (rather than ID). The default is C<false>.

=item C<< jql >>

A L<JQL|https://confluence.atlassian.com/x/egORLQ> expression.

=item C<< maxResults >>

The maximum number of items to return per page.

=item C<< properties >>

A list of up to 5 issue properties to include in the results. This parameter accepts a comma-separated list.

=item C<< startAt >>

The index of the first item to return in the page of results (page offset). The base index is C<0>.

=item C<< validateQuery >>

Determines how to validate the JQL query and treat the validation results. Supported values:

=over

=item *

C<strict> Returns a 400 response code if any errors are found, along with a list of all errors (and warnings).


=item *

C<warn> Returns all errors as warnings.


=item *

C<none> No validation is performed.


=item *

C<true> I<Deprecated> A legacy synonym for C<strict>.


=item *

C<false> I<Deprecated> A legacy synonym for C<warn>.


=back

The default is C<strict>.

Note: If the JQL is not correctly formed a 400 response code is returned, regardless of the C<validateQuery> value.

=back

Returns a L<< JIRA::API::SearchResults >>.

=cut

sub _build_searchForIssuesUsingJqlPost_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/search';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::SearchRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub searchForIssuesUsingJqlPost( $self, %options ) {
    my $tx = $self->_build_searchForIssuesUsingJqlPost_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SearchResults->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the JQL query is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueSecurityLevel >>

  my $res = $client->getIssueSecurityLevel()->get;

Get issue security level

=head3 Parameters

=over 4

=item B<< id >>

The ID of the issue security level.

=back


Returns a L<< JIRA::API::SecurityLevel >>.

=cut

sub _build_getIssueSecurityLevel_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/securitylevel/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueSecurityLevel( $self, %options ) {
    my $tx = $self->_build_getIssueSecurityLevel_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::SecurityLevel->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue security level is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getServerInfo >>

  my $res = $client->getServerInfo()->get;

Get Jira instance info

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::ServerInformation >>.

=cut

sub _build_getServerInfo_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/serverInfo';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getServerInfo( $self, %options ) {
    my $tx = $self->_build_getServerInfo_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ServerInformation->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIssueNavigatorDefaultColumns >>

  my $res = $client->getIssueNavigatorDefaultColumns()->get;

Get issue navigator default columns

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::ColumnItem >>.

=cut

sub _build_getIssueNavigatorDefaultColumns_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/settings/columns';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIssueNavigatorDefaultColumns( $self, %options ) {
    my $tx = $self->_build_getIssueNavigatorDefaultColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ColumnItem->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setIssueNavigatorDefaultColumns >>

  my $res = $client->setIssueNavigatorDefaultColumns()->get;

Set issue navigator default columns

=head3 Parameters

=over 4

=back


Returns a L<<  >>.

=cut

sub _build_setIssueNavigatorDefaultColumns_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/settings/columns';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => '*/*',
        }
        # XXX Need to fill the body
        # => $body,
    );

    return $tx
}


sub setIssueNavigatorDefaultColumns( $self, %options ) {
    my $tx = $self->_build_setIssueNavigatorDefaultColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if invalid parameters are passed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if a navigable field value is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getStatuses >>

  my $res = $client->getStatuses()->get;

Get all statuses

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::StatusDetails >>.

=cut

sub _build_getStatuses_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/status';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getStatuses( $self, %options ) {
    my $tx = $self->_build_getStatuses_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::StatusDetails->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getStatus >>

  my $res = $client->getStatus()->get;

Get status

=head3 Parameters

=over 4

=item B<< idOrName >>

The ID or name of the status.

=back


Returns a L<< JIRA::API::StatusDetails >>.

=cut

sub _build_getStatus_request( $self, %options ) {
    croak "Missing required parameter 'idOrName'"
        unless exists $options{ 'idOrName' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/status/{idOrName}' );
    my $path = $template->process(
              'idOrName' => delete $options{'idOrName'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getStatus( $self, %options ) {
    my $tx = $self->_build_getStatus_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::StatusDetails->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the status is not found. * the status is not associated with a workflow. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getStatusCategories >>

  my $res = $client->getStatusCategories()->get;

Get all status categories

=head3 Parameters

=over 4

=back


Returns an array of L<< JIRA::API::StatusCategory >>.

=cut

sub _build_getStatusCategories_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/statuscategory';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getStatusCategories( $self, %options ) {
    my $tx = $self->_build_getStatusCategories_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::StatusCategory->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getStatusCategory >>

  my $res = $client->getStatusCategory()->get;

Get status category

=head3 Parameters

=over 4

=item B<< idOrKey >>

The ID or key of the status category.

=back


Returns a L<< JIRA::API::StatusCategory >>.

=cut

sub _build_getStatusCategory_request( $self, %options ) {
    croak "Missing required parameter 'idOrKey'"
        unless exists $options{ 'idOrKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/statuscategory/{idOrKey}' );
    my $path = $template->process(
              'idOrKey' => delete $options{'idOrKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getStatusCategory( $self, %options ) {
    my $tx = $self->_build_getStatusCategory_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::StatusCategory->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the status category is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteStatusesById >>

  my $res = $client->deleteStatusesById()->get;

Bulk delete Statuses

=head3 Parameters

=over 4

=item B<< id >>

The list of status IDs. To include multiple IDs, provide an ampersand-separated list. For example, id=10000&id=10001.

Min items C<1>, Max items C<50>

=back


Returns a L<<  >>.

=cut

sub _build_deleteStatusesById_request( $self, %options ) {
    my $method = 'DELETE';
    my $path = '/rest/api/3/statuses';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'id' => delete $options{'id'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteStatusesById( $self, %options ) {
    my $tx = $self->_build_deleteStatusesById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing, or the caller doesn't have permissions to perform the operation.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getStatusesById >>

  my $res = $client->getStatusesById()->get;

Bulk get statuses

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<usages> Returns the project and issue types that use the status in their workflow.


=back

=item B<< id >>

The list of status IDs. To include multiple IDs, provide an ampersand-separated list. For example, id=10000&id=10001.

Min items C<1>, Max items C<50>

=back


Returns an array of L<< JIRA::API::JiraStatus >>.

=cut

sub _build_getStatusesById_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/statuses';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'id' => delete $options{'id'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getStatusesById( $self, %options ) {
    my $tx = $self->_build_getStatusesById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::JiraStatus->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing, or the caller doesn't have permissions to perform the operation.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createStatuses >>

  my $res = $client->createStatuses()->get;

Bulk create statuses

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< scope >>

The scope of the status.

=item C<< statuses >>

Details of the statuses being created.

=back

Returns an array of L<< JIRA::API::JiraStatus >>.

=cut

sub _build_createStatuses_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/statuses';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::StatusCreateRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createStatuses( $self, %options ) {
    my $tx = $self->_build_createStatuses_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::JiraStatus->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing, or the caller doesn't have permissions to perform the operation.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateStatuses >>

  my $res = $client->updateStatuses()->get;

Bulk update statuses

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< statuses >>

The list of statuses that will be updated.

=back

Returns a L<<  >>.

=cut

sub _build_updateStatuses_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/statuses';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::StatusUpdateRequest->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateStatuses( $self, %options ) {
    my $tx = $self->_build_updateStatuses_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing, or the caller doesn't have permissions to perform the operation.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< search >>

  my $res = $client->search()->get;

Search statuses paginated

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<usages> Returns the project and issue types that use the status in their workflow.


=back

=item B<< projectId >>

The project the status is part of or null for global statuses.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< searchString >>

Term to match status names against or null to search for all statuses in the search scope.

=item B<< statusCategory >>

Category of the status to filter by. The supported values are: C<TODO>, C<IN_PROGRESS>, and C<DONE>.

=back


Returns a L<< JIRA::API::PageOfStatuses >>.

=cut

sub _build_search_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/statuses/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
        maybe 'projectId' => delete $options{'projectId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'searchString' => delete $options{'searchString'},
        maybe 'statusCategory' => delete $options{'statusCategory'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub search( $self, %options ) {
    my $tx = $self->_build_search_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageOfStatuses->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing, or the caller doesn't have permissions to perform the operation.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getTask >>

  my $res = $client->getTask()->get;

Get task

=head3 Parameters

=over 4

=item B<< taskId >>

The ID of the task.

=back


Returns a L<< JIRA::API::TaskProgressBeanObject >>.

=cut

sub _build_getTask_request( $self, %options ) {
    croak "Missing required parameter 'taskId'"
        unless exists $options{ 'taskId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/task/{taskId}' );
    my $path = $template->process(
              'taskId' => delete $options{'taskId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getTask( $self, %options ) {
    my $tx = $self->_build_getTask_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanObject->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the task is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< cancelTask >>

  my $res = $client->cancelTask()->get;

Cancel task

=head3 Parameters

=over 4

=item B<< taskId >>

The ID of the task.

=back


Returns a L<<  >>.
Returns an array of L<< JIRA::API:: >>.
Returns an array of L<< JIRA::API:: >>.
Returns an array of L<< JIRA::API:: >>.
Returns an array of L<< JIRA::API:: >>.

=cut

sub _build_cancelTask_request( $self, %options ) {
    croak "Missing required parameter 'taskId'"
        unless exists $options{ 'taskId' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/task/{taskId}/cancel' );
    my $path = $template->process(
              'taskId' => delete $options{'taskId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub cancelTask( $self, %options ) {
    my $tx = $self->_build_cancelTask_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 202 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if cancellation of the task is not possible.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { $_
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { $_
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { $_
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the task is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { $_
 } $payload->@* ],

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUiModifications >>

  my $res = $client->getUiModifications()->get;

Get UI modifications

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< expand >>

Use expand to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<data> Returns UI modification data.


=item *

C<contexts> Returns UI modification contexts.


=back

=back


Returns a L<< JIRA::API::PageBeanUiModificationDetails >>.

=cut

sub _build_getUiModifications_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/uiModifications';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUiModifications( $self, %options ) {
    my $tx = $self->_build_getUiModifications_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanUiModificationDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not from a Forge app.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createUiModification >>

  my $res = $client->createUiModification()->get;

Create UI modification

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< contexts >>

List of contexts of the UI modification. The maximum number of contexts is 1000.

=item C<< data >>

The data of the UI modification. The maximum size of the data is 50000 characters.

=item C<< description >>

The description of the UI modification. The maximum length is 255 characters.

=item C<< name >>

The name of the UI modification. The maximum length is 255 characters.

=back

Returns a L<< JIRA::API::UiModificationIdentifiers >>.

=cut

sub _build_createUiModification_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/uiModifications';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateUiModificationDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createUiModification( $self, %options ) {
    my $tx = $self->_build_createUiModification_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the UI modification is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::UiModificationIdentifiers->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not from a Forge app.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if a project or an issue type in the context are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteUiModification >>

  my $res = $client->deleteUiModification()->get;

Delete UI modification

=head3 Parameters

=over 4

=item B<< uiModificationId >>

The ID of the UI modification.

=back


Returns a L<<  >>.

=cut

sub _build_deleteUiModification_request( $self, %options ) {
    croak "Missing required parameter 'uiModificationId'"
        unless exists $options{ 'uiModificationId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/uiModifications/{uiModificationId}' );
    my $path = $template->process(
              'uiModificationId' => delete $options{'uiModificationId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteUiModification( $self, %options ) {
    my $tx = $self->_build_deleteUiModification_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the UI modification is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not from a Forge app.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the UI modification is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateUiModification >>

  my $res = $client->updateUiModification()->get;

Update UI modification

=head3 Parameters

=over 4

=item B<< uiModificationId >>

The ID of the UI modification.

=back


=head3 Options

=over 4

=item C<< contexts >>

List of contexts of the UI modification. The maximum number of contexts is 1000. If provided, replaces all existing contexts.

=item C<< data >>

The data of the UI modification. The maximum size of the data is 50000 characters.

=item C<< description >>

The description of the UI modification. The maximum length is 255 characters.

=item C<< name >>

The name of the UI modification. The maximum length is 255 characters.

=back

Returns a L<<  >>.

=cut

sub _build_updateUiModification_request( $self, %options ) {
    croak "Missing required parameter 'uiModificationId'"
        unless exists $options{ 'uiModificationId' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/uiModifications/{uiModificationId}' );
    my $path = $template->process(
              'uiModificationId' => delete $options{'uiModificationId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::UpdateUiModificationDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateUiModification( $self, %options ) {
    my $tx = $self->_build_updateUiModification_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the UI modification is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the request is not from a Forge app.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the UI modification, a project or an issue type in the context are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAvatars >>

  my $res = $client->getAvatars()->get;

Get avatars

=head3 Parameters

=over 4

=item B<< type >>

The avatar type.

=item B<< entityId >>

The ID of the item the avatar is associated with.

=back


Returns a L<< JIRA::API::Avatars >>.

=cut

sub _build_getAvatars_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };
    croak "Missing required parameter 'entityId'"
        unless exists $options{ 'entityId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/universal_avatar/type/{type}/owner/{entityId}' );
    my $path = $template->process(
              'type' => delete $options{'type'},
              'entityId' => delete $options{'entityId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAvatars( $self, %options ) {
    my $tx = $self->_build_getAvatars_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Avatars->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the avatar type is invalid, the associated item ID is missing, or the item is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< storeAvatar >>

  my $res = $client->storeAvatar()->get;

Load avatar

=head3 Parameters

=over 4

=item B<< type >>

The avatar type.

=item B<< entityId >>

The ID of the item the avatar is associated with.

=item B<< x >>

The X coordinate of the top-left corner of the crop region.

=item B<< y >>

The Y coordinate of the top-left corner of the crop region.

=item B<< size >>

The length of each side of the crop region.

=back


Returns a L<< JIRA::API::Avatar >>.

=cut

sub _build_storeAvatar_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };
    croak "Missing required parameter 'entityId'"
        unless exists $options{ 'entityId' };
    croak "Missing required parameter 'size'"
        unless exists $options{ 'size' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/universal_avatar/type/{type}/owner/{entityId}' );
    my $path = $template->process(
              'type' => delete $options{'type'},
              'entityId' => delete $options{'entityId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'x' => delete $options{'x'},
        maybe 'y' => delete $options{'y'},
              'size' => delete $options{'size'},
    );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => '*/*',
        }
        # XXX Need to fill the body
        # => $body,
    );

    return $tx
}


sub storeAvatar( $self, %options ) {
    my $tx = $self->_build_storeAvatar_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Avatar->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * an image isn't included in the request. * the image type is unsupported. * the crop parameters extend the crop area beyond the edge of the image.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the avatar type is invalid, the associated item ID is missing, or the item is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteAvatar >>

  my $res = $client->deleteAvatar()->get;

Delete avatar

=head3 Parameters

=over 4

=item B<< type >>

The avatar type.

=item B<< owningObjectId >>

The ID of the item the avatar is associated with.

=item B<< id >>

The ID of the avatar.

=back



=cut

sub _build_deleteAvatar_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };
    croak "Missing required parameter 'owningObjectId'"
        unless exists $options{ 'owningObjectId' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/universal_avatar/type/{type}/owner/{owningObjectId}/avatar/{id}' );
    my $path = $template->process(
              'type' => delete $options{'type'},
              'owningObjectId' => delete $options{'owningObjectId'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteAvatar( $self, %options ) {
    my $tx = $self->_build_deleteAvatar_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have permission to delete the avatar, the avatar is not deletable.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the avatar type, associated item ID, or avatar ID is invalid.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAvatarImageByType >>

  my $res = $client->getAvatarImageByType()->get;

Get avatar image by type

=head3 Parameters

=over 4

=item B<< type >>

The icon type of the avatar.

=item B<< size >>

The size of the avatar image. If not provided the default size is returned.

=item B<< format >>

The format to return the avatar image in. If not provided the original content format is returned.

=back


Returns a L<< object >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getAvatarImageByType_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/universal_avatar/view/type/{type}' );
    my $path = $template->process(
              'type' => delete $options{'type'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'size' => delete $options{'size'},
        maybe 'format' => delete $options{'format'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => '*/*,application/json,image/png,image/svg+xml',
        }
    );

    return $tx
}


sub getAvatarImageByType( $self, %options ) {
    my $tx = $self->_build_getAvatarImageByType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if an avatar is not found or an avatar matching the requested size is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAvatarImageByID >>

  my $res = $client->getAvatarImageByID()->get;

Get avatar image by ID

=head3 Parameters

=over 4

=item B<< type >>

The icon type of the avatar.

=item B<< id >>

The ID of the avatar.

=item B<< size >>

The size of the avatar image. If not provided the default size is returned.

=item B<< format >>

The format to return the avatar image in. If not provided the original content format is returned.

=back


Returns a L<< object >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getAvatarImageByID_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/universal_avatar/view/type/{type}/avatar/{id}' );
    my $path = $template->process(
              'type' => delete $options{'type'},
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'size' => delete $options{'size'},
        maybe 'format' => delete $options{'format'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => '*/*,application/json,image/png,image/svg+xml',
        }
    );

    return $tx
}


sub getAvatarImageByID( $self, %options ) {
    my $tx = $self->_build_getAvatarImageByID_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if an avatar is not found or an avatar matching the requested size is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAvatarImageByOwner >>

  my $res = $client->getAvatarImageByOwner()->get;

Get avatar image by owner

=head3 Parameters

=over 4

=item B<< type >>

The icon type of the avatar.

=item B<< entityId >>

The ID of the project or issue type the avatar belongs to.

=item B<< size >>

The size of the avatar image. If not provided the default size is returned.

=item B<< format >>

The format to return the avatar image in. If not provided the original content format is returned.

=back


Returns a L<< object >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getAvatarImageByOwner_request( $self, %options ) {
    croak "Missing required parameter 'type'"
        unless exists $options{ 'type' };
    croak "Missing required parameter 'entityId'"
        unless exists $options{ 'entityId' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/universal_avatar/view/type/{type}/owner/{entityId}' );
    my $path = $template->process(
              'type' => delete $options{'type'},
              'entityId' => delete $options{'entityId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'size' => delete $options{'size'},
        maybe 'format' => delete $options{'format'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => '*/*,application/json,image/png,image/svg+xml',
        }
    );

    return $tx
}


sub getAvatarImageByOwner( $self, %options ) {
    my $tx = $self->_build_getAvatarImageByOwner_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if an avatar is not found or an avatar matching the requested size is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq '*/*' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/png' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'image/svg+xml' ) {
                my $payload = $resp->body();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< removeUser >>

  my $res = $client->removeUser()->get;

Delete user

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< key >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back



=cut

sub _build_removeUser_request( $self, %options ) {
    croak "Missing required parameter 'accountId'"
        unless exists $options{ 'accountId' };

    my $method = 'DELETE';
    my $path = '/rest/api/3/user';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'accountId' => delete $options{'accountId'},
        maybe 'username' => delete $options{'username'},
        maybe 'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub removeUser( $self, %options ) {
    my $tx = $self->_build_removeUser_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the user cannot be removed.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUser >>

  my $res = $client->getUser()->get;

Get user

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>. Required.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide> for details.

=item B<< key >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide> for details.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about users in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<groups> includes all groups and nested groups to which the user belongs.


=item *

C<applicationRoles> includes details of all the applications to which the user has access.


=back

=back


Returns a L<< JIRA::API::User >>.

=cut

sub _build_getUser_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'username' => delete $options{'username'},
        maybe 'key' => delete $options{'key'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUser( $self, %options ) {
    my $tx = $self->_build_getUser_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::User->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the calling user does not have the *Browse users and groups* global permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createUser >>

  my $res = $client->createUser()->get;

Create user

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< applicationKeys >>

Deprecated, do not use.

=item C<< displayName >>

This property is no longer available. If the user has an Atlassian account, their display name is not changed. If the user does not have an Atlassian account, they are sent an email asking them set up an account.

=item C<< emailAddress >>

The email address for the user.

=item C<< key >>

This property is no longer available. See the L<migration guide|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item C<< name >>

This property is no longer available. See the L<migration guide|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item C<< password >>

This property is no longer available. If the user has an Atlassian account, their password is not changed. If the user does not have an Atlassian account, they are sent an email asking them set up an account.

=item C<< self >>

The URL of the user.

=back

Returns a L<< JIRA::API::User >>.

=cut

sub _build_createUser_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/user';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::NewUserDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createUser( $self, %options ) {
    my $tx = $self->_build_createUser_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::User->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid or the number of licensed users is exceeded.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findBulkAssignableUsers >>

  my $res = $client->findBulkAssignableUsers()->get;

Find users assignable to projects

=head3 Parameters

=over 4

=item B<< query >>

A query string that is matched against user attributes, such as C<displayName> and C<emailAddress>, to find relevant users. The string can match the prefix of the attribute's value. For example, I<query=john> matches a user with a C<displayName> of I<John Smith> and a user with an C<emailAddress> of I<johnson@example.com>. Required, unless C<accountId> is specified.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

A query string that is matched exactly against user C<accountId>. Required, unless C<query> is specified.

=item B<< projectKeys >>

A list of project keys (case sensitive). This parameter accepts a comma-separated list.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_findBulkAssignableUsers_request( $self, %options ) {
    croak "Missing required parameter 'projectKeys'"
        unless exists $options{ 'projectKeys' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/assignable/multiProjectSearch';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'query' => delete $options{'query'},
        maybe 'username' => delete $options{'username'},
        maybe 'accountId' => delete $options{'accountId'},
              'projectKeys' => delete $options{'projectKeys'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findBulkAssignableUsers( $self, %options ) {
    my $tx = $self->_build_findBulkAssignableUsers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `projectKeys` is missing. * `query` or `accountId` is missing. * `query` and `accountId` are provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if one or more of the projects is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findAssignableUsers >>

  my $res = $client->findAssignableUsers()->get;

Find users assignable to issues

=head3 Parameters

=over 4

=item B<< query >>

A query string that is matched against user attributes, such as C<displayName>, and C<emailAddress>, to find relevant users. The string can match the prefix of the attribute's value. For example, I<query=john> matches a user with a C<displayName> of I<John Smith> and a user with an C<emailAddress> of I<johnson@example.com>. Required, unless C<username> or C<accountId> is specified.

=item B<< sessionId >>

The sessionId of this request. SessionId is the same until the assignee is set.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

A query string that is matched exactly against user C<accountId>. Required, unless C<query> is specified.

=item B<< project >>

The project ID or project key (case sensitive). Required, unless C<issueKey> is specified.

=item B<< issueKey >>

The key of the issue. Required, unless C<project> is specified.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return. This operation may return less than the maximum number of items even if more are available. The operation fetches users up to the maximum and then, from the fetched users, returns only the users that can be assigned to the issue.

=item B<< actionDescriptorId >>

The ID of the transition.

=item B<< recommend >>

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_findAssignableUsers_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user/assignable/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'query' => delete $options{'query'},
        maybe 'sessionId' => delete $options{'sessionId'},
        maybe 'username' => delete $options{'username'},
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'project' => delete $options{'project'},
        maybe 'issueKey' => delete $options{'issueKey'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'actionDescriptorId' => delete $options{'actionDescriptorId'},
        maybe 'recommend' => delete $options{'recommend'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findAssignableUsers( $self, %options ) {
    my $tx = $self->_build_findAssignableUsers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `issueKey` or `project` is missing. * `query` or `accountId` is missing. * `query` and `accountId` are provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the project, issue, or transition is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkGetUsers >>

  my $res = $client->bulkGetUsers()->get;

Bulk get users

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< username >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< key >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

The account ID of a user. To specify multiple users, pass multiple C<accountId> parameters. For example, C<accountId=5b10a2844c20165700ede21g&accountId=5b10ac8d82e05b22cc7d4ef5>.

=back


Returns a L<< JIRA::API::PageBeanUser >>.

=cut

sub _build_bulkGetUsers_request( $self, %options ) {
    croak "Missing required parameter 'accountId'"
        unless exists $options{ 'accountId' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/bulk';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'username' => delete $options{'username'},
        maybe 'key' => delete $options{'key'},
              'accountId' => delete $options{'accountId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub bulkGetUsers( $self, %options ) {
    my $tx = $self->_build_bulkGetUsers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanUser->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `accountID` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< bulkGetUsersMigration >>

  my $res = $client->bulkGetUsersMigration()->get;

Get account IDs for users

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< username >>

Username of a user. To specify multiple users, pass multiple copies of this parameter. For example, C<username=fred&username=barney>. Required if C<key> isn't provided. Cannot be provided if C<key> is present.

=item B<< key >>

Key of a user. To specify multiple users, pass multiple copies of this parameter. For example, C<key=fred&key=barney>. Required if C<username> isn't provided. Cannot be provided if C<username> is present.

=back


Returns an array of L<< JIRA::API::UserMigrationBean >>.

=cut

sub _build_bulkGetUsersMigration_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user/bulk/migration';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'username' => delete $options{'username'},
        maybe 'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub bulkGetUsersMigration( $self, %options ) {
    my $tx = $self->_build_bulkGetUsersMigration_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::UserMigrationBean->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `key` or `username`
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< resetUserColumns >>

  my $res = $client->resetUserColumns()->get;

Reset user default columns

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back



=cut

sub _build_resetUserColumns_request( $self, %options ) {
    my $method = 'DELETE';
    my $path = '/rest/api/3/user/columns';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'username' => delete $options{'username'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub resetUserColumns( $self, %options ) {
    my $tx = $self->_build_resetUserColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUserDefaultColumns >>

  my $res = $client->getUserDefaultColumns()->get;

Get user default columns

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< username >>

This parameter is no longer available See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back


Returns an array of L<< JIRA::API::ColumnItem >>.

=cut

sub _build_getUserDefaultColumns_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user/columns';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'username' => delete $options{'username'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUserDefaultColumns( $self, %options ) {
    my $tx = $self->_build_getUserDefaultColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::ColumnItem->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the requested user is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setUserColumns >>

  my $res = $client->setUserColumns()->get;

Set user default columns

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=back


Returns a L<<  >>.

=cut

sub _build_setUserColumns_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/user/columns';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
    );

    my $request = JIRA::API::->new( \%options );
    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => '*/*',
        }
        # XXX Need to fill the body
        # => $body,
    );

    return $tx
}


sub setUserColumns( $self, %options ) {
    my $tx = $self->_build_setUserColumns_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the requested user is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 500 ) {
            # Returned if an invalid issue table column ID is sent.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUserEmail >>

  my $res = $client->getUserEmail()->get;

Get user email

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, C<5b10ac8d82e05b22cc7d4ef5>.

=back


Returns a L<< JIRA::API::UnrestrictedUserEmail >>.

=cut

sub _build_getUserEmail_request( $self, %options ) {
    croak "Missing required parameter 'accountId'"
        unless exists $options{ 'accountId' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/email';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'accountId' => delete $options{'accountId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUserEmail( $self, %options ) {
    my $tx = $self->_build_getUserEmail_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::UnrestrictedUserEmail->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the calling app is not approved to use this API.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing from the request (for example if a user is trying to access this API).
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if a user with the given `accountId` doesn't exist
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 503 ) {
            # Indicates the API is not currently enabled
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUserEmailBulk >>

  my $res = $client->getUserEmailBulk()->get;

Get user email bulk

=head3 Parameters

=over 4

=item B<< accountId >>

The account IDs of the users for which emails are required. An C<accountId> is an identifier that uniquely identifies the user across all Atlassian products. For example, C<5b10ac8d82e05b22cc7d4ef5>. Note, this should be treated as an opaque identifier (that is, do not assume any structure in the value).

=back


Returns a L<< JIRA::API::UnrestrictedUserEmail >>.

=cut

sub _build_getUserEmailBulk_request( $self, %options ) {
    croak "Missing required parameter 'accountId'"
        unless exists $options{ 'accountId' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/email/bulk';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'accountId' => delete $options{'accountId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUserEmailBulk( $self, %options ) {
    my $tx = $self->_build_getUserEmailBulk_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::UnrestrictedUserEmail->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the calling app is not approved to use this API.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect, or missing from the request (for example if a user is trying to access this API).
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 503 ) {
            # Indicates the API is not currently enabled.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUserGroups >>

  my $res = $client->getUserGroups()->get;

Get user groups

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< key >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back


Returns an array of L<< JIRA::API::GroupName >>.

=cut

sub _build_getUserGroups_request( $self, %options ) {
    croak "Missing required parameter 'accountId'"
        unless exists $options{ 'accountId' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/groups';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'accountId' => delete $options{'accountId'},
        maybe 'username' => delete $options{'username'},
        maybe 'key' => delete $options{'key'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUserGroups( $self, %options ) {
    my $tx = $self->_build_getUserGroups_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::GroupName->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the calling user does not have the *Browse users and groups* global permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUsersWithAllPermissions >>

  my $res = $client->findUsersWithAllPermissions()->get;

Find users with permissions

=head3 Parameters

=over 4

=item B<< query >>

A query string that is matched against user attributes, such as C<displayName> and C<emailAddress>, to find relevant users. The string can match the prefix of the attribute's value. For example, I<query=john> matches a user with a C<displayName> of I<John Smith> and a user with an C<emailAddress> of I<johnson@example.com>. Required, unless C<accountId> is specified.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

A query string that is matched exactly against user C<accountId>. Required, unless C<query> is specified.

=item B<< permissions >>

A comma separated list of permissions. Permissions can be specified as any:

=over

=item *

permission returned by L<Get all permissions|#api-rest-api-3-permissions-get>.


=item *

custom project permission added by Connect apps.


=item *

(deprecated) one of the following:


=over

=item *

ASSIGNABLE_USER


=item *

ASSIGN_ISSUE


=item *

ATTACHMENT_DELETE_ALL


=item *

ATTACHMENT_DELETE_OWN


=item *

BROWSE


=item *

CLOSE_ISSUE


=item *

COMMENT_DELETE_ALL


=item *

COMMENT_DELETE_OWN


=item *

COMMENT_EDIT_ALL


=item *

COMMENT_EDIT_OWN


=item *

COMMENT_ISSUE


=item *

CREATE_ATTACHMENT


=item *

CREATE_ISSUE


=item *

DELETE_ISSUE


=item *

EDIT_ISSUE


=item *

LINK_ISSUE


=item *

MANAGE_WATCHER_LIST


=item *

MODIFY_REPORTER


=item *

MOVE_ISSUE


=item *

PROJECT_ADMIN


=item *

RESOLVE_ISSUE


=item *

SCHEDULE_ISSUE


=item *

SET_ISSUE_SECURITY


=item *

TRANSITION_ISSUE


=item *

VIEW_VERSION_CONTROL


=item *

VIEW_VOTERS_AND_WATCHERS


=item *

VIEW_WORKFLOW_READONLY


=item *

WORKLOG_DELETE_ALL


=item *

WORKLOG_DELETE_OWN


=item *

WORKLOG_EDIT_ALL


=item *

WORKLOG_EDIT_OWN


=item *

WORK_ISSUE


=back



=back

=item B<< issueKey >>

The issue key for the issue.

=item B<< projectKey >>

The project key for the project (case sensitive).

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_findUsersWithAllPermissions_request( $self, %options ) {
    croak "Missing required parameter 'permissions'"
        unless exists $options{ 'permissions' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/permission/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'query' => delete $options{'query'},
        maybe 'username' => delete $options{'username'},
        maybe 'accountId' => delete $options{'accountId'},
              'permissions' => delete $options{'permissions'},
        maybe 'issueKey' => delete $options{'issueKey'},
        maybe 'projectKey' => delete $options{'projectKey'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUsersWithAllPermissions( $self, %options ) {
    my $tx = $self->_build_findUsersWithAllPermissions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `issueKey` or `projectKey` is missing. * `query` or `accountId` is missing. * `query` and `accountId` are provided. * `permissions` is empty or contains an invalid entry.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or project is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUsersForPicker >>

  my $res = $client->findUsersForPicker()->get;

Find users for picker

=head3 Parameters

=over 4

=item B<< query >>

A query string that is matched against user attributes, such as C<displayName>, and C<emailAddress>, to find relevant users. The string can match the prefix of the attribute's value. For example, I<query=john> matches a user with a C<displayName> of I<John Smith> and a user with an C<emailAddress> of I<johnson@example.com>.

=item B<< maxResults >>

The maximum number of items to return. The total number of matched users is returned in C<total>.

=item B<< showAvatar >>

Include the URI to the user's avatar.

=item B<< exclude >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< excludeAccountIds >>

A list of account IDs to exclude from the search results. This parameter accepts a comma-separated list. Multiple account IDs can also be provided using an ampersand-separated list. For example, C<excludeAccountIds=5b10a2844c20165700ede21g,5b10a0effa615349cb016cd8&excludeAccountIds=5b10ac8d82e05b22cc7d4ef5>. Cannot be provided with C<exclude>.

=item B<< avatarSize >>

=item B<< excludeConnectUsers >>

=back


Returns a L<< JIRA::API::FoundUsers >>.

=cut

sub _build_findUsersForPicker_request( $self, %options ) {
    croak "Missing required parameter 'query'"
        unless exists $options{ 'query' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/picker';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'query' => delete $options{'query'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'showAvatar' => delete $options{'showAvatar'},
        maybe 'exclude' => delete $options{'exclude'},
        maybe 'excludeAccountIds' => delete $options{'excludeAccountIds'},
        maybe 'avatarSize' => delete $options{'avatarSize'},
        maybe 'excludeConnectUsers' => delete $options{'excludeConnectUsers'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUsersForPicker( $self, %options ) {
    my $tx = $self->_build_findUsersForPicker_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FoundUsers->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `exclude` and `excludeAccountIds` are provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUserPropertyKeys >>

  my $res = $client->getUserPropertyKeys()->get;

Get user property keys

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< userKey >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< username >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=back


Returns a L<< JIRA::API::PropertyKeys >>.

=cut

sub _build_getUserPropertyKeys_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user/properties';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'userKey' => delete $options{'userKey'},
        maybe 'username' => delete $options{'username'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUserPropertyKeys( $self, %options ) {
    my $tx = $self->_build_getUserPropertyKeys_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `accountId` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteUserProperty >>

  my $res = $client->deleteUserProperty()->get;

Delete user property

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< userKey >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< username >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< propertyKey >>

The key of the user's property.

=back



=cut

sub _build_deleteUserProperty_request( $self, %options ) {
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/user/properties/{propertyKey}' );
    my $path = $template->process(
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'userKey' => delete $options{'userKey'},
        maybe 'username' => delete $options{'username'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteUserProperty( $self, %options ) {
    my $tx = $self->_build_deleteUserProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the user property is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if `accountId` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user or the property is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getUserProperty >>

  my $res = $client->getUserProperty()->get;

Get user property

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< userKey >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< username >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< propertyKey >>

The key of the user's property.

=back


Returns a L<< JIRA::API::EntityProperty >>.

=cut

sub _build_getUserProperty_request( $self, %options ) {
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/user/properties/{propertyKey}' );
    my $path = $template->process(
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'userKey' => delete $options{'userKey'},
        maybe 'username' => delete $options{'username'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getUserProperty( $self, %options ) {
    my $tx = $self->_build_getUserProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `accountId` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setUserProperty >>

  my $res = $client->setUserProperty()->get;

Set user property

=head3 Parameters

=over 4

=item B<< accountId >>

The account ID of the user, which uniquely identifies the user across all Atlassian products. For example, I<5b10ac8d82e05b22cc7d4ef5>.

=item B<< userKey >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< username >>

This parameter is no longer available and will be removed from the documentation soon. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< propertyKey >>

The key of the user's property. The maximum length is 255 characters.

=back


Returns a L<<  >>.
Returns a L<<  >>.

=cut

sub _build_setUserProperty_request( $self, %options ) {
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/user/properties/{propertyKey}' );
    my $path = $template->process(
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'userKey' => delete $options{'userKey'},
        maybe 'username' => delete $options{'username'},
    );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setUserProperty( $self, %options ) {
    my $tx = $self->_build_setUserProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the user property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned if the user property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if `accountId` is missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission or is not accessing their user record.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the user is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 405 ) {
            # Returned if the property key is not specified.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUsers >>

  my $res = $client->findUsers()->get;

Find users

=head3 Parameters

=over 4

=item B<< query >>

A query string that is matched against user attributes ( C<displayName>, and C<emailAddress>) to find relevant users. The string can match the prefix of the attribute's value. For example, I<query=john> matches a user with a C<displayName> of I<John Smith> and a user with an C<emailAddress> of I<johnson@example.com>. Required, unless C<accountId> or C<property> is specified.

=item B<< username >>

=item B<< accountId >>

A query string that is matched exactly against a user C<accountId>. Required, unless C<query> or C<property> is specified.

=item B<< startAt >>

The index of the first item to return in a page of filtered results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< property >>

A query string used to search properties. Property keys are specified by path, so property keys containing dot (.) or equals (=) characters cannot be used. The query string cannot be specified using a JSON object. Example: To search for the value of C<nested> from C<{"something":{"nested":1,"other":2}}> use C<thepropertykey.something.nested=1>. Required, unless C<accountId> or C<query> is specified.

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_findUsers_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'query' => delete $options{'query'},
        maybe 'username' => delete $options{'username'},
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'property' => delete $options{'property'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUsers( $self, %options ) {
    my $tx = $self->_build_findUsers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `accountId`, `query` or `property` is missing. * `query` and `accountId` are provided. * `property` parameter is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUsersByQuery >>

  my $res = $client->findUsersByQuery()->get;

Find users by query

=head3 Parameters

=over 4

=item B<< query >>

The search query.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanUser >>.

=cut

sub _build_findUsersByQuery_request( $self, %options ) {
    croak "Missing required parameter 'query'"
        unless exists $options{ 'query' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/search/query';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'query' => delete $options{'query'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUsersByQuery( $self, %options ) {
    my $tx = $self->_build_findUsersByQuery_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanUser->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the query is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 408 ) {
            # Returned if the search is timed out.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUserKeysByQuery >>

  my $res = $client->findUserKeysByQuery()->get;

Find user keys by query

=head3 Parameters

=over 4

=item B<< query >>

The search query.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanUserKey >>.

=cut

sub _build_findUserKeysByQuery_request( $self, %options ) {
    croak "Missing required parameter 'query'"
        unless exists $options{ 'query' };

    my $method = 'GET';
    my $path = '/rest/api/3/user/search/query/key';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'query' => delete $options{'query'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUserKeysByQuery( $self, %options ) {
    my $tx = $self->_build_findUserKeysByQuery_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanUserKey->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the query is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 408 ) {
            # Returned if the search is timed out.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< findUsersWithBrowsePermission >>

  my $res = $client->findUsersWithBrowsePermission()->get;

Find users with browse permission

=head3 Parameters

=over 4

=item B<< query >>

A query string that is matched against user attributes, such as C<displayName> and C<emailAddress>, to find relevant users. The string can match the prefix of the attribute's value. For example, I<query=john> matches a user with a C<displayName> of I<John Smith> and a user with an C<emailAddress> of I<johnson@example.com>. Required, unless C<accountId> is specified.

=item B<< username >>

This parameter is no longer available. See the L<deprecation notice|https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/> for details.

=item B<< accountId >>

A query string that is matched exactly against user C<accountId>. Required, unless C<query> is specified.

=item B<< issueKey >>

The issue key for the issue. Required, unless C<projectKey> is specified.

=item B<< projectKey >>

The project key for the project (case sensitive). Required, unless C<issueKey> is specified.

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_findUsersWithBrowsePermission_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/user/viewissue/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'query' => delete $options{'query'},
        maybe 'username' => delete $options{'username'},
        maybe 'accountId' => delete $options{'accountId'},
        maybe 'issueKey' => delete $options{'issueKey'},
        maybe 'projectKey' => delete $options{'projectKey'},
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub findUsersWithBrowsePermission( $self, %options ) {
    my $tx = $self->_build_findUsersWithBrowsePermission_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * `issueKey` or `projectKey` is missing. * `query` or `accountId` is missing. * `query` and `accountId` are provided.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the issue or project is not found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 429 ) {
            # Returned if the rate limit is exceeded. User search endpoints share a collective rate limit for the tenant, in addition to Jira's normal rate limiting you may receive a rate limit for user search. Please respect the Retry-After header.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllUsersDefault >>

  my $res = $client->getAllUsersDefault()->get;

Get all users default

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return.

=item B<< maxResults >>

The maximum number of items to return.

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_getAllUsersDefault_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/users';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllUsersDefault( $self, %options ) {
    my $tx = $self->_build_getAllUsersDefault_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the request takes longer than 10 seconds or is interrupted.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllUsers >>

  my $res = $client->getAllUsers()->get;

Get all users

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return.

=item B<< maxResults >>

The maximum number of items to return.

=back


Returns an array of L<< JIRA::API::User >>.

=cut

sub _build_getAllUsers_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/users/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllUsers( $self, %options ) {
    my $tx = $self->_build_getAllUsers_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::User->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user doesn't have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 409 ) {
            # Returned if the request takes longer than 10 seconds or is interrupted.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createVersion >>

  my $res = $client->createVersion()->get;

Create version

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< archived >>

Indicates that the version is archived. Optional when creating or updating a version.

=item C<< description >>

The description of the version. Optional when creating or updating a version.

=item C<< expand >>

Use L<expand|em>#expansion> to include additional information about version in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<operations> Returns the list of operations available for this version.


=item *

C<issuesstatus> Returns the count of issues in this version for each of the status categories I<to do>, I<in progress>, I<done>, and I<unmapped>. The I<unmapped> property contains a count of issues with a status other than I<to do>, I<in progress>, and I<done>.


=back

Optional for create and update.

=item C<< id >>

The ID of the version.

=item C<< issuesStatusForFixVersion >>

If the expand option C<issuesstatus> is used, returns the count of issues in this version for each of the status categories I<to do>, I<in progress>, I<done>, and I<unmapped>. The I<unmapped> property contains a count of issues with a status other than I<to do>, I<in progress>, and I<done>.

=item C<< moveUnfixedIssuesTo >>

The URL of the self link to the version to which all unfixed issues are moved when a version is released. Not applicable when creating a version. Optional when updating a version.

=item C<< name >>

The unique name of the version. Required when creating a version. Optional when updating a version. The maximum length is 255 characters.

=item C<< operations >>

If the expand option C<operations> is used, returns the list of operations available for this version.

=item C<< overdue >>

Indicates that the version is overdue.

=item C<< project >>

Deprecated. Use C<projectId>.

=item C<< projectId >>

The ID of the project to which this version is attached. Required when creating a version. Not applicable when updating a version.

=item C<< releaseDate >>

The release date of the version. Expressed in ISO 8601 format (yyyy-mm-dd). Optional when creating or updating a version.

=item C<< released >>

Indicates that the version is released. If the version is released a request to release again is ignored. Not applicable when creating a version. Optional when updating a version.

=item C<< self >>

The URL of the version.

=item C<< startDate >>

The start date of the version. Expressed in ISO 8601 format (yyyy-mm-dd). Optional when creating or updating a version.

=item C<< userReleaseDate >>

The date on which work on this version is expected to finish, expressed in the instance's I<Day/Month/Year Format> date format.

=item C<< userStartDate >>

The date on which work on this version is expected to start, expressed in the instance's I<Day/Month/Year Format> date format.

=back

Returns a L<< JIRA::API::Version >>.

=cut

sub _build_createVersion_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/version';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::Version->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createVersion( $self, %options ) {
    my $tx = $self->_build_createVersion_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Version->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the project is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteVersion >>

  my $res = $client->deleteVersion()->get;

Delete version

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version.

=item B<< moveFixIssuesTo >>

The ID of the version to update C<fixVersion> to when the field contains the deleted version. The replacement version must be in the same project as the version being deleted and cannot be the version being deleted.

=item B<< moveAffectedIssuesTo >>

The ID of the version to update C<affectedVersion> to when the field contains the deleted version. The replacement version must be in the same project as the version being deleted and cannot be the version being deleted.

=back



=cut

sub _build_deleteVersion_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/version/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'moveFixIssuesTo' => delete $options{'moveFixIssuesTo'},
        maybe 'moveAffectedIssuesTo' => delete $options{'moveAffectedIssuesTo'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteVersion( $self, %options ) {
    my $tx = $self->_build_deleteVersion_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the version is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if: * the authentication credentials are incorrect. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the version is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getVersion >>

  my $res = $client->getVersion()->get;

Get version

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about version in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<operations> Returns the list of operations available for this version.


=item *

C<issuesstatus> Returns the count of issues in this version for each of the status categories I<to do>, I<in progress>, I<done>, and I<unmapped>. The I<unmapped> property represents the number of issues with a status other than I<to do>, I<in progress>, and I<done>.


=back

=back


Returns a L<< JIRA::API::Version >>.

=cut

sub _build_getVersion_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/version/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getVersion( $self, %options ) {
    my $tx = $self->_build_getVersion_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Version->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the version is not found or the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateVersion >>

  my $res = $client->updateVersion()->get;

Update version

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version.

=back


=head3 Options

=over 4

=item C<< archived >>

Indicates that the version is archived. Optional when creating or updating a version.

=item C<< description >>

The description of the version. Optional when creating or updating a version.

=item C<< expand >>

Use L<expand|em>#expansion> to include additional information about version in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<operations> Returns the list of operations available for this version.


=item *

C<issuesstatus> Returns the count of issues in this version for each of the status categories I<to do>, I<in progress>, I<done>, and I<unmapped>. The I<unmapped> property contains a count of issues with a status other than I<to do>, I<in progress>, and I<done>.


=back

Optional for create and update.

=item C<< id >>

The ID of the version.

=item C<< issuesStatusForFixVersion >>

If the expand option C<issuesstatus> is used, returns the count of issues in this version for each of the status categories I<to do>, I<in progress>, I<done>, and I<unmapped>. The I<unmapped> property contains a count of issues with a status other than I<to do>, I<in progress>, and I<done>.

=item C<< moveUnfixedIssuesTo >>

The URL of the self link to the version to which all unfixed issues are moved when a version is released. Not applicable when creating a version. Optional when updating a version.

=item C<< name >>

The unique name of the version. Required when creating a version. Optional when updating a version. The maximum length is 255 characters.

=item C<< operations >>

If the expand option C<operations> is used, returns the list of operations available for this version.

=item C<< overdue >>

Indicates that the version is overdue.

=item C<< project >>

Deprecated. Use C<projectId>.

=item C<< projectId >>

The ID of the project to which this version is attached. Required when creating a version. Not applicable when updating a version.

=item C<< releaseDate >>

The release date of the version. Expressed in ISO 8601 format (yyyy-mm-dd). Optional when creating or updating a version.

=item C<< released >>

Indicates that the version is released. If the version is released a request to release again is ignored. Not applicable when creating a version. Optional when updating a version.

=item C<< self >>

The URL of the version.

=item C<< startDate >>

The start date of the version. Expressed in ISO 8601 format (yyyy-mm-dd). Optional when creating or updating a version.

=item C<< userReleaseDate >>

The date on which work on this version is expected to finish, expressed in the instance's I<Day/Month/Year Format> date format.

=item C<< userStartDate >>

The date on which work on this version is expected to start, expressed in the instance's I<Day/Month/Year Format> date format.

=back

Returns a L<< JIRA::API::Version >>.

=cut

sub _build_updateVersion_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/version/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::Version->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateVersion( $self, %options ) {
    my $tx = $self->_build_updateVersion_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Version->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the request is invalid. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the version is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< mergeVersions >>

  my $res = $client->mergeVersions()->get;

Merge versions

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version to delete.

=item B<< moveIssuesTo >>

The ID of the version to merge into.

=back


Returns a L<<  >>.

=cut

sub _build_mergeVersions_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'moveIssuesTo'"
        unless exists $options{ 'moveIssuesTo' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/version/{id}/mergeto/{moveIssuesTo}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'moveIssuesTo' => delete $options{'moveIssuesTo'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub mergeVersions( $self, %options ) {
    my $tx = $self->_build_mergeVersions_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the version is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if: * the authentication credentials are incorrect or missing. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the version to be deleted or the version to merge to are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< moveVersion >>

  my $res = $client->moveVersion()->get;

Move version

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version to be moved.

=back


=head3 Options

=over 4

=item C<< after >>

The URL (self link) of the version after which to place the moved version. Cannot be used with C<position>.

=item C<< position >>

An absolute position in which to place the moved version. Cannot be used with C<after>.

=back

Returns a L<< JIRA::API::Version >>.

=cut

sub _build_moveVersion_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/version/{id}/move' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::VersionMoveBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub moveVersion( $self, %options ) {
    my $tx = $self->_build_moveVersion_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::Version->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * no body parameters are provided. * `after` and `position` are provided. * `position` is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if: * the authentication credentials are incorrect or missing * the user does not have the required commissions.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the version or move after version are not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getVersionRelatedIssues >>

  my $res = $client->getVersionRelatedIssues()->get;

Get version's related issues count

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version.

=back


Returns a L<< JIRA::API::VersionIssueCounts >>.

=cut

sub _build_getVersionRelatedIssues_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/version/{id}/relatedIssueCounts' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getVersionRelatedIssues( $self, %options ) {
    my $tx = $self->_build_getVersionRelatedIssues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::VersionIssueCounts->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the version is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteAndReplaceVersion >>

  my $res = $client->deleteAndReplaceVersion()->get;

Delete and replace version

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version.

=back


=head3 Options

=over 4

=item C<< customFieldReplacementList >>

An array of custom field IDs (C<customFieldId>) and version IDs (C<moveTo>) to update when the fields contain the deleted version.

=item C<< moveAffectedIssuesTo >>

The ID of the version to update C<affectedVersion> to when the field contains the deleted version.

=item C<< moveFixIssuesTo >>

The ID of the version to update C<fixVersion> to when the field contains the deleted version.

=back

Returns a L<<  >>.

=cut

sub _build_deleteAndReplaceVersion_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/version/{id}/removeAndSwap' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DeleteAndReplaceVersionBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub deleteAndReplaceVersion( $self, %options ) {
    my $tx = $self->_build_deleteAndReplaceVersion_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the version is deleted.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the version to delete is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getVersionUnresolvedIssues >>

  my $res = $client->getVersionUnresolvedIssues()->get;

Get version's unresolved issues count

=head3 Parameters

=over 4

=item B<< id >>

The ID of the version.

=back


Returns a L<< JIRA::API::VersionUnresolvedIssuesCount >>.

=cut

sub _build_getVersionUnresolvedIssues_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/version/{id}/unresolvedIssueCount' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getVersionUnresolvedIssues( $self, %options ) {
    my $tx = $self->_build_getVersionUnresolvedIssues_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::VersionUnresolvedIssuesCount->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the version is not found. * the user does not have the required permissions.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWebhookById >>

  my $res = $client->deleteWebhookById()->get;

Delete webhooks by ID

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< webhookIds >>

A list of webhook IDs.

=back

Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deleteWebhookById_request( $self, %options ) {
    my $method = 'DELETE';
    my $path = '/rest/api/3/webhook';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ContainerForWebhookIDs->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub deleteWebhookById( $self, %options ) {
    my $tx = $self->_build_deleteWebhookById_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 202 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the list of webhook IDs is missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller isn't an app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDynamicWebhooksForApp >>

  my $res = $client->getDynamicWebhooksForApp()->get;

Get dynamic webhooks for app

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanWebhook >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getDynamicWebhooksForApp_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/webhook';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDynamicWebhooksForApp( $self, %options ) {
    my $tx = $self->_build_getDynamicWebhooksForApp_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanWebhook->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller isn't an app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< registerDynamicWebhooks >>

  my $res = $client->registerDynamicWebhooks()->get;

Register dynamic webhooks

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< url >>

The URL that specifies where to send the webhooks. This URL must use the same base URL as the Connect app. Only a single URL per app is allowed to be registered.

=item C<< webhooks >>

A list of webhooks.

=back

Returns a L<< JIRA::API::ContainerForRegisteredWebhooks >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_registerDynamicWebhooks_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/webhook';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WebhookRegistrationDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub registerDynamicWebhooks( $self, %options ) {
    my $tx = $self->_build_registerDynamicWebhooks_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ContainerForRegisteredWebhooks->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller isn't an app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getFailedWebhooks >>

  my $res = $client->getFailedWebhooks()->get;

Get failed webhooks

=head3 Parameters

=over 4

=item B<< maxResults >>

The maximum number of webhooks to return per page. If obeying the maxResults directive would result in records with the same failure time being split across pages, the directive is ignored and all records with the same failure time included on the page.

=item B<< after >>

The time after which any webhook failure must have occurred for the record to be returned, expressed as milliseconds since the UNIX epoch.

=back


Returns a L<< JIRA::API::FailedWebhooks >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getFailedWebhooks_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/webhook/failed';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'after' => delete $options{'after'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getFailedWebhooks( $self, %options ) {
    my $tx = $self->_build_getFailedWebhooks_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::FailedWebhooks->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # 400 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller is not a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< refreshWebhooks >>

  my $res = $client->refreshWebhooks()->get;

Extend webhook life

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< webhookIds >>

A list of webhook IDs.

=back

Returns a L<< JIRA::API::WebhooksExpirationDate >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_refreshWebhooks_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/webhook/refresh';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ContainerForWebhookIDs->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub refreshWebhooks( $self, %options ) {
    my $tx = $self->_build_refreshWebhooks_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WebhooksExpirationDate->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller isn't an app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllWorkflows >>

  my $res = $client->getAllWorkflows()->get;

Get all workflows

=head3 Parameters

=over 4

=item B<< workflowName >>

The name of the workflow to be returned. Only one workflow can be specified.

=back


Returns an array of L<< JIRA::API::DeprecatedWorkflow >>.

=cut

sub _build_getAllWorkflows_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/workflow';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'workflowName' => delete $options{'workflowName'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllWorkflows( $self, %options ) {
    my $tx = $self->_build_getAllWorkflows_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::DeprecatedWorkflow->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createWorkflow >>

  my $res = $client->createWorkflow()->get;

Create workflow

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< description >>

The description of the workflow. The maximum length is 1000 characters.

=item C<< name >>

The name of the workflow. The name must be unique. The maximum length is 255 characters. Characters can be separated by a whitespace but the name cannot start or end with a whitespace.

=item C<< statuses >>

The statuses of the workflow. Any status that does not include a transition is added to the workflow without a transition.

=item C<< transitions >>

The transitions of the workflow. For the request to be valid, these transitions must:

=over

=item *

include one I<initial> transition.


=item *

not use the same name for a I<global> and I<directed> transition.


=item *

have a unique name for each I<global> transition.


=item *

have a unique 'to' status for each I<global> transition.


=item *

have unique names for each transition from a status.


=item *

not have a 'from' status on I<initial> and I<global> transitions.


=item *

have a 'from' status on I<directed> transitions.


=back

All the transition statuses must be included in C<statuses>.

=back

Returns a L<< JIRA::API::WorkflowIDs >>.

=cut

sub _build_createWorkflow_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/workflow';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::CreateWorkflowDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createWorkflow( $self, %options ) {
    my $tx = $self->_build_createWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the workflow is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowIDs->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if one or more statuses is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowTransitionRuleConfigurations >>

  my $res = $client->getWorkflowTransitionRuleConfigurations()->get;

Get workflow transition rule configurations

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< types >>

The types of the transition rules to return.

=item B<< keys >>

The transition rule class keys, as defined in the Connect app descriptor, of the transition rules to return.

=item B<< workflowNames >>

EXPERIMENTAL: The list of workflow names to filter by.

=item B<< withTags >>

EXPERIMENTAL: The list of C<tags> to filter by.

=item B<< draft >>

EXPERIMENTAL: Whether draft or published workflows are returned. If not provided, both workflow types are returned.

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts C<transition>, which, for each rule, returns information about the transition the rule is assigned to.

=back


Returns a L<< JIRA::API::PageBeanWorkflowTransitionRules >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getWorkflowTransitionRuleConfigurations_request( $self, %options ) {
    croak "Missing required parameter 'types'"
        unless exists $options{ 'types' };

    my $method = 'GET';
    my $path = '/rest/api/3/workflow/rule/config';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
              'types' => delete $options{'types'},
        maybe 'keys' => delete $options{'keys'},
        maybe 'workflowNames' => delete $options{'workflowNames'},
        maybe 'withTags' => delete $options{'withTags'},
        maybe 'draft' => delete $options{'draft'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowTransitionRuleConfigurations( $self, %options ) {
    my $tx = $self->_build_getWorkflowTransitionRuleConfigurations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanWorkflowTransitionRules->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller is not a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if any transition rule type is not supported.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateWorkflowTransitionRuleConfigurations >>

  my $res = $client->updateWorkflowTransitionRuleConfigurations()->get;

Update workflow transition rule configurations

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< workflows >>

The list of workflows with transition rules to update.

=back

Returns a L<< JIRA::API::WorkflowTransitionRulesUpdateErrors >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_updateWorkflowTransitionRuleConfigurations_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/workflow/rule/config';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowTransitionRulesUpdate->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateWorkflowTransitionRuleConfigurations( $self, %options ) {
    my $tx = $self->_build_updateWorkflowTransitionRuleConfigurations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowTransitionRulesUpdateErrors->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller is not a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowTransitionRuleConfigurations >>

  my $res = $client->deleteWorkflowTransitionRuleConfigurations()->get;

Delete workflow transition rule configurations

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< workflows >>

The list of workflows with transition rules to delete.

=back

Returns a L<< JIRA::API::WorkflowTransitionRulesUpdateErrors >>.
Returns a L<< JIRA::API::ErrorCollection >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_deleteWorkflowTransitionRuleConfigurations_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/workflow/rule/config/delete';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowsWithTransitionRulesDetails->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub deleteWorkflowTransitionRuleConfigurations( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowTransitionRuleConfigurations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowTransitionRulesUpdateErrors->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } elsif( $resp->code == 403 ) {
            # Returned if the caller is not a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowsPaginated >>

  my $res = $client->getWorkflowsPaginated()->get;

Get workflows paginated

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=item B<< workflowName >>

The name of a workflow to return. To include multiple workflows, provide an ampersand-separated list. For example, C<workflowName=name1&workflowName=name2>.

=item B<< expand >>

Use L<expand|#expansion> to include additional information in the response. This parameter accepts a comma-separated list. Expand options include:

=over

=item *

C<transitions> For each workflow, returns information about the transitions inside the workflow.


=item *

C<transitions.rules> For each workflow transition, returns information about its rules. Transitions are included automatically if this expand is requested.


=item *

C<transitions.properties> For each workflow transition, returns information about its properties. Transitions are included automatically if this expand is requested.


=item *

C<statuses> For each workflow, returns information about the statuses inside the workflow.


=item *

C<statuses.properties> For each workflow status, returns information about its properties. Statuses are included automatically if this expand is requested.


=item *

C<default> For each workflow, returns information about whether this is the default workflow.


=item *

C<schemes> For each workflow, returns information about the workflow schemes the workflow is assigned to.


=item *

C<projects> For each workflow, returns information about the projects the workflow is assigned to, through workflow schemes.


=item *

C<hasDraftWorkflow> For each workflow, returns information about whether the workflow has a draft version.


=item *

C<operations> For each workflow, returns information about the actions that can be undertaken on the workflow.


=back

=item B<< queryString >>

String used to perform a case-insensitive partial match with workflow name.

=item B<< orderBy >>

L<Order|#ordering> the results by a field:

=over

=item *

C<name> Sorts by workflow name.


=item *

C<created> Sorts by create time.


=item *

C<updated> Sorts by update time.


=back

=item B<< isActive >>

Filters active and inactive workflows.

=back


Returns a L<< JIRA::API::PageBeanWorkflow >>.
Returns a L<< JIRA::API::ErrorCollection >>.

=cut

sub _build_getWorkflowsPaginated_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/workflow/search';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
        maybe 'workflowName' => delete $options{'workflowName'},
        maybe 'expand' => delete $options{'expand'},
        maybe 'queryString' => delete $options{'queryString'},
        maybe 'orderBy' => delete $options{'orderBy'},
        maybe 'isActive' => delete $options{'isActive'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowsPaginated( $self, %options ) {
    my $tx = $self->_build_getWorkflowsPaginated_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanWorkflow->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorCollection->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowTransitionProperty >>

  my $res = $client->deleteWorkflowTransitionProperty()->get;

Delete workflow transition property

=head3 Parameters

=over 4

=item B<< transitionId >>

The ID of the transition. To get the ID, view the workflow in text mode in the Jira admin settings. The ID is shown next to the transition.

=item B<< key >>

The name of the transition property to delete, also known as the name of the property.

=item B<< workflowName >>

The name of the workflow that the transition belongs to.

=item B<< workflowMode >>

The workflow status. Set to C<live> for inactive workflows or C<draft> for draft workflows. Active workflows cannot be edited.

=back



=cut

sub _build_deleteWorkflowTransitionProperty_request( $self, %options ) {
    croak "Missing required parameter 'transitionId'"
        unless exists $options{ 'transitionId' };
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflow/transitions/{transitionId}/properties' );
    my $path = $template->process(
              'transitionId' => delete $options{'transitionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'key' => delete $options{'key'},
              'workflowName' => delete $options{'workflowName'},
        maybe 'workflowMode' => delete $options{'workflowMode'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteWorkflowTransitionProperty( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowTransitionProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 304 ) {
            # Returned if no changes were made by the request. For example, trying to delete a property that cannot be found.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow transition is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowTransitionProperties >>

  my $res = $client->getWorkflowTransitionProperties()->get;

Get workflow transition properties

=head3 Parameters

=over 4

=item B<< transitionId >>

The ID of the transition. To get the ID, view the workflow in text mode in the Jira administration console. The ID is shown next to the transition.

=item B<< includeReservedKeys >>

Some properties with keys that have the I<jira.> prefix are reserved, which means they are not editable. To include these properties in the results, set this parameter to I<true>.

=item B<< key >>

The key of the property being returned, also known as the name of the property. If this parameter is not specified, all properties on the transition are returned.

=item B<< workflowName >>

The name of the workflow that the transition belongs to.

=item B<< workflowMode >>

The workflow status. Set to I<live> for active and inactive workflows, or I<draft> for draft workflows.

=back


Returns a L<< JIRA::API::WorkflowTransitionProperty >>.

=cut

sub _build_getWorkflowTransitionProperties_request( $self, %options ) {
    croak "Missing required parameter 'transitionId'"
        unless exists $options{ 'transitionId' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflow/transitions/{transitionId}/properties' );
    my $path = $template->process(
              'transitionId' => delete $options{'transitionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'includeReservedKeys' => delete $options{'includeReservedKeys'},
        maybe 'key' => delete $options{'key'},
              'workflowName' => delete $options{'workflowName'},
        maybe 'workflowMode' => delete $options{'workflowMode'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowTransitionProperties( $self, %options ) {
    my $tx = $self->_build_getWorkflowTransitionProperties_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowTransitionProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have admin permission
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow transition or property is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createWorkflowTransitionProperty >>

  my $res = $client->createWorkflowTransitionProperty()->get;

Create workflow transition property

=head3 Parameters

=over 4

=item B<< transitionId >>

The ID of the transition. To get the ID, view the workflow in text mode in the Jira admin settings. The ID is shown next to the transition.

=item B<< key >>

The key of the property being added, also known as the name of the property. Set this to the same value as the C<key> defined in the request body.

=item B<< workflowName >>

The name of the workflow that the transition belongs to.

=item B<< workflowMode >>

The workflow status. Set to I<live> for inactive workflows or I<draft> for draft workflows. Active workflows cannot be edited.

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the transition property.

=item C<< key >>

The key of the transition property. Also known as the name of the transition property.

=item C<< value >>

The value of the transition property.

=back

Returns a L<< JIRA::API::WorkflowTransitionProperty >>.

=cut

sub _build_createWorkflowTransitionProperty_request( $self, %options ) {
    croak "Missing required parameter 'transitionId'"
        unless exists $options{ 'transitionId' };
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/workflow/transitions/{transitionId}/properties' );
    my $path = $template->process(
              'transitionId' => delete $options{'transitionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'key' => delete $options{'key'},
              'workflowName' => delete $options{'workflowName'},
        maybe 'workflowMode' => delete $options{'workflowMode'},
    );

    my $request = JIRA::API::WorkflowTransitionProperty->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createWorkflowTransitionProperty( $self, %options ) {
    my $tx = $self->_build_createWorkflowTransitionProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowTransitionProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if a workflow property with the same key is present on the transition.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow transition is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateWorkflowTransitionProperty >>

  my $res = $client->updateWorkflowTransitionProperty()->get;

Update workflow transition property

=head3 Parameters

=over 4

=item B<< transitionId >>

The ID of the transition. To get the ID, view the workflow in text mode in the Jira admin settings. The ID is shown next to the transition.

=item B<< key >>

The key of the property being updated, also known as the name of the property. Set this to the same value as the C<key> defined in the request body.

=item B<< workflowName >>

The name of the workflow that the transition belongs to.

=item B<< workflowMode >>

The workflow status. Set to C<live> for inactive workflows or C<draft> for draft workflows. Active workflows cannot be edited.

=back


=head3 Options

=over 4

=item C<< id >>

The ID of the transition property.

=item C<< key >>

The key of the transition property. Also known as the name of the transition property.

=item C<< value >>

The value of the transition property.

=back

Returns a L<< JIRA::API::WorkflowTransitionProperty >>.

=cut

sub _build_updateWorkflowTransitionProperty_request( $self, %options ) {
    croak "Missing required parameter 'transitionId'"
        unless exists $options{ 'transitionId' };
    croak "Missing required parameter 'key'"
        unless exists $options{ 'key' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflow/transitions/{transitionId}/properties' );
    my $path = $template->process(
              'transitionId' => delete $options{'transitionId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'key' => delete $options{'key'},
              'workflowName' => delete $options{'workflowName'},
        maybe 'workflowMode' => delete $options{'workflowMode'},
    );

    my $request = JIRA::API::WorkflowTransitionProperty->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateWorkflowTransitionProperty( $self, %options ) {
    my $tx = $self->_build_updateWorkflowTransitionProperty_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # 200 response
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowTransitionProperty->new($payload),

                );
            }
        } elsif( $resp->code == 304 ) {
            # Returned if no changes were made by the request. For example, attempting to update a property with its current value.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow transition is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteInactiveWorkflow >>

  my $res = $client->deleteInactiveWorkflow()->get;

Delete inactive workflow

=head3 Parameters

=over 4

=item B<< entityId >>

The entity ID of the workflow.

=back



=cut

sub _build_deleteInactiveWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'entityId'"
        unless exists $options{ 'entityId' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflow/{entityId}' );
    my $path = $template->process(
              'entityId' => delete $options{'entityId'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteInactiveWorkflow( $self, %options ) {
    my $tx = $self->_build_deleteInactiveWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the workflow is deleted.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getAllWorkflowSchemes >>

  my $res = $client->getAllWorkflowSchemes()->get;

Get all workflow schemes

=head3 Parameters

=over 4

=item B<< startAt >>

The index of the first item to return in a page of results (page offset).

=item B<< maxResults >>

The maximum number of items to return per page.

=back


Returns a L<< JIRA::API::PageBeanWorkflowScheme >>.

=cut

sub _build_getAllWorkflowSchemes_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/workflowscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'startAt' => delete $options{'startAt'},
        maybe 'maxResults' => delete $options{'maxResults'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getAllWorkflowSchemes( $self, %options ) {
    my $tx = $self->_build_getAllWorkflowSchemes_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PageBeanWorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createWorkflowScheme >>

  my $res = $client->createWorkflowScheme()->get;

Create workflow scheme

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< defaultWorkflow >>

The name of the default workflow for the workflow scheme. The default workflow has I<All Unassigned Issue Types> assigned to it in Jira. If C<defaultWorkflow> is not specified when creating a workflow scheme, it is set to I<Jira Workflow (jira)>.

=item C<< description >>

The description of the workflow scheme.

=item C<< draft >>

Whether the workflow scheme is a draft or not.

=item C<< id >>

The ID of the workflow scheme.

=item C<< issueTypeMappings >>

The issue type to workflow mappings, where each mapping is an issue type ID and workflow name pair. Note that an issue type can only be mapped to one workflow in a workflow scheme.

=item C<< issueTypes >>

The issue types available in Jira.

=item C<< lastModified >>

The date-time that the draft workflow scheme was last modified. A modification is a change to the issue type-project mappings only. This property does not apply to non-draft workflows.

=item C<< lastModifiedUser >>

The user that last modified the draft workflow scheme. A modification is a change to the issue type-project mappings only. This property does not apply to non-draft workflows.

=item C<< name >>

The name of the workflow scheme. The name must be unique. The maximum length is 255 characters. Required when creating a workflow scheme.

=item C<< originalDefaultWorkflow >>

For draft workflow schemes, this property is the name of the default workflow for the original workflow scheme. The default workflow has I<All Unassigned Issue Types> assigned to it in Jira.

=item C<< originalIssueTypeMappings >>

For draft workflow schemes, this property is the issue type to workflow mappings for the original workflow scheme, where each mapping is an issue type ID and workflow name pair. Note that an issue type can only be mapped to one workflow in a workflow scheme.

=item C<< self >>

=item C<< updateDraftIfNeeded >>

Whether to create or update a draft workflow scheme when updating an active workflow scheme. An active workflow scheme is a workflow scheme that is used by at least one project. The following examples show how this property works:

=over

=item *

Update an active workflow scheme with C<updateDraftIfNeeded> set to C<true>: If a draft workflow scheme exists, it is updated. Otherwise, a draft workflow scheme is created.


=item *

Update an active workflow scheme with C<updateDraftIfNeeded> set to C<false>: An error is returned, as active workflow schemes cannot be updated.


=item *

Update an inactive workflow scheme with C<updateDraftIfNeeded> set to C<true>: The workflow scheme is updated, as inactive workflow schemes do not require drafts to update.


=back

Defaults to C<false>.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_createWorkflowScheme_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/workflowscheme';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub createWorkflowScheme( $self, %options ) {
    my $tx = $self->_build_createWorkflowScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowSchemeProjectAssociations >>

  my $res = $client->getWorkflowSchemeProjectAssociations()->get;

Get workflow scheme project associations

=head3 Parameters

=over 4

=item B<< projectId >>

The ID of a project to return the workflow schemes for. To include multiple projects, provide an ampersand-Jim: oneseparated list. For example, C<projectId=10000&projectId=10001>.

=back


Returns a L<< JIRA::API::ContainerOfWorkflowSchemeAssociations >>.

=cut

sub _build_getWorkflowSchemeProjectAssociations_request( $self, %options ) {
    croak "Missing required parameter 'projectId'"
        unless exists $options{ 'projectId' };

    my $method = 'GET';
    my $path = '/rest/api/3/workflowscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'projectId' => delete $options{'projectId'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowSchemeProjectAssociations( $self, %options ) {
    my $tx = $self->_build_getWorkflowSchemeProjectAssociations_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ContainerOfWorkflowSchemeAssociations->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< assignSchemeToProject >>

  my $res = $client->assignSchemeToProject()->get;

Assign workflow scheme to project

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< projectId >>

The ID of the project.

=item C<< workflowSchemeId >>

The ID of the workflow scheme. If the workflow scheme ID is C<null>, the operation assigns the default workflow scheme.

=back

Returns a L<<  >>.

=cut

sub _build_assignSchemeToProject_request( $self, %options ) {
    my $method = 'PUT';
    my $path = '/rest/api/3/workflowscheme/project';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowSchemeProjectAssociation->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub assignSchemeToProject( $self, %options ) {
    my $tx = $self->_build_assignSchemeToProject_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the required permissions.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or the project are not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowScheme >>

  my $res = $client->deleteWorkflowScheme()->get;

Delete workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme. Find this ID by editing the desired workflow scheme in Jira. The ID is shown in the URL as C<schemeId>. For example, I<schemeId=10301>.

=back


Returns a L<<  >>.

=cut

sub _build_deleteWorkflowScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteWorkflowScheme( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the scheme is active.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowScheme >>

  my $res = $client->getWorkflowScheme()->get;

Get workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme. Find this ID by editing the desired workflow scheme in Jira. The ID is shown in the URL as C<schemeId>. For example, I<schemeId=10301>.

=item B<< returnDraftIfExists >>

Returns the workflow scheme's draft rather than scheme itself, if set to true. If the workflow scheme does not have a draft, then the workflow scheme is returned.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_getWorkflowScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'returnDraftIfExists' => delete $options{'returnDraftIfExists'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowScheme( $self, %options ) {
    my $tx = $self->_build_getWorkflowScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateWorkflowScheme >>

  my $res = $client->updateWorkflowScheme()->get;

Update workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme. Find this ID by editing the desired workflow scheme in Jira. The ID is shown in the URL as C<schemeId>. For example, I<schemeId=10301>.

=back


=head3 Options

=over 4

=item C<< defaultWorkflow >>

The name of the default workflow for the workflow scheme. The default workflow has I<All Unassigned Issue Types> assigned to it in Jira. If C<defaultWorkflow> is not specified when creating a workflow scheme, it is set to I<Jira Workflow (jira)>.

=item C<< description >>

The description of the workflow scheme.

=item C<< draft >>

Whether the workflow scheme is a draft or not.

=item C<< id >>

The ID of the workflow scheme.

=item C<< issueTypeMappings >>

The issue type to workflow mappings, where each mapping is an issue type ID and workflow name pair. Note that an issue type can only be mapped to one workflow in a workflow scheme.

=item C<< issueTypes >>

The issue types available in Jira.

=item C<< lastModified >>

The date-time that the draft workflow scheme was last modified. A modification is a change to the issue type-project mappings only. This property does not apply to non-draft workflows.

=item C<< lastModifiedUser >>

The user that last modified the draft workflow scheme. A modification is a change to the issue type-project mappings only. This property does not apply to non-draft workflows.

=item C<< name >>

The name of the workflow scheme. The name must be unique. The maximum length is 255 characters. Required when creating a workflow scheme.

=item C<< originalDefaultWorkflow >>

For draft workflow schemes, this property is the name of the default workflow for the original workflow scheme. The default workflow has I<All Unassigned Issue Types> assigned to it in Jira.

=item C<< originalIssueTypeMappings >>

For draft workflow schemes, this property is the issue type to workflow mappings for the original workflow scheme, where each mapping is an issue type ID and workflow name pair. Note that an issue type can only be mapped to one workflow in a workflow scheme.

=item C<< self >>

=item C<< updateDraftIfNeeded >>

Whether to create or update a draft workflow scheme when updating an active workflow scheme. An active workflow scheme is a workflow scheme that is used by at least one project. The following examples show how this property works:

=over

=item *

Update an active workflow scheme with C<updateDraftIfNeeded> set to C<true>: If a draft workflow scheme exists, it is updated. Otherwise, a draft workflow scheme is created.


=item *

Update an active workflow scheme with C<updateDraftIfNeeded> set to C<false>: An error is returned, as active workflow schemes cannot be updated.


=item *

Update an inactive workflow scheme with C<updateDraftIfNeeded> set to C<true>: The workflow scheme is updated, as inactive workflow schemes do not require drafts to update.


=back

Defaults to C<false>.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_updateWorkflowScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateWorkflowScheme( $self, %options ) {
    my $tx = $self->_build_updateWorkflowScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< createWorkflowSchemeDraftFromParent >>

  my $res = $client->createWorkflowSchemeDraftFromParent()->get;

Create draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the active workflow scheme that the draft is created from.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_createWorkflowSchemeDraftFromParent_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/createdraft' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub createWorkflowSchemeDraftFromParent( $self, %options ) {
    my $tx = $self->_build_createWorkflowSchemeDraftFromParent_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 201 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteDefaultWorkflow >>

  my $res = $client->deleteDefaultWorkflow()->get;

Delete default workflow

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< updateDraftIfNeeded >>

Set to true to create or update the draft of a workflow scheme and delete the mapping from the draft, when the workflow scheme cannot be edited. Defaults to C<false>.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_deleteDefaultWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/default' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'updateDraftIfNeeded' => delete $options{'updateDraftIfNeeded'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteDefaultWorkflow( $self, %options ) {
    my $tx = $self->_build_deleteDefaultWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the workflow scheme cannot be edited and `updateDraftIfNeeded` is not `true`.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDefaultWorkflow >>

  my $res = $client->getDefaultWorkflow()->get;

Get default workflow

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< returnDraftIfExists >>

Set to C<true> to return the default workflow for the workflow scheme's draft rather than scheme itself. If the workflow scheme does not have a draft, then the default workflow for the workflow scheme is returned.

=back


Returns a L<< JIRA::API::DefaultWorkflow >>.

=cut

sub _build_getDefaultWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/default' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'returnDraftIfExists' => delete $options{'returnDraftIfExists'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDefaultWorkflow( $self, %options ) {
    my $tx = $self->_build_getDefaultWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::DefaultWorkflow->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateDefaultWorkflow >>

  my $res = $client->updateDefaultWorkflow()->get;

Update default workflow

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=back


=head3 Options

=over 4

=item C<< updateDraftIfNeeded >>

Whether a draft workflow scheme is created or updated when updating an active workflow scheme. The draft is updated with the new default workflow. Defaults to C<false>.

=item C<< workflow >>

The name of the workflow to set as the default workflow.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_updateDefaultWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/default' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DefaultWorkflow->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateDefaultWorkflow( $self, %options ) {
    my $tx = $self->_build_updateDefaultWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the workflow scheme cannot be edited and `updateDraftIfNeeded` is not `true`.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowSchemeDraft >>

  my $res = $client->deleteWorkflowSchemeDraft()->get;

Delete draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the active workflow scheme that the draft was created from.

=back



=cut

sub _build_deleteWorkflowSchemeDraft_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteWorkflowSchemeDraft( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowSchemeDraft_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission..
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the original active workflow scheme is not found. * the original active workflow scheme does not have a draft.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowSchemeDraft >>

  my $res = $client->getWorkflowSchemeDraft()->get;

Get draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the active workflow scheme that the draft was created from.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_getWorkflowSchemeDraft_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowSchemeDraft( $self, %options ) {
    my $tx = $self->_build_getWorkflowSchemeDraft_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the original active workflow scheme is not found. * the original active workflow scheme does not have a draft.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateWorkflowSchemeDraft >>

  my $res = $client->updateWorkflowSchemeDraft()->get;

Update draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the active workflow scheme that the draft was created from.

=back


=head3 Options

=over 4

=item C<< defaultWorkflow >>

The name of the default workflow for the workflow scheme. The default workflow has I<All Unassigned Issue Types> assigned to it in Jira. If C<defaultWorkflow> is not specified when creating a workflow scheme, it is set to I<Jira Workflow (jira)>.

=item C<< description >>

The description of the workflow scheme.

=item C<< draft >>

Whether the workflow scheme is a draft or not.

=item C<< id >>

The ID of the workflow scheme.

=item C<< issueTypeMappings >>

The issue type to workflow mappings, where each mapping is an issue type ID and workflow name pair. Note that an issue type can only be mapped to one workflow in a workflow scheme.

=item C<< issueTypes >>

The issue types available in Jira.

=item C<< lastModified >>

The date-time that the draft workflow scheme was last modified. A modification is a change to the issue type-project mappings only. This property does not apply to non-draft workflows.

=item C<< lastModifiedUser >>

The user that last modified the draft workflow scheme. A modification is a change to the issue type-project mappings only. This property does not apply to non-draft workflows.

=item C<< name >>

The name of the workflow scheme. The name must be unique. The maximum length is 255 characters. Required when creating a workflow scheme.

=item C<< originalDefaultWorkflow >>

For draft workflow schemes, this property is the name of the default workflow for the original workflow scheme. The default workflow has I<All Unassigned Issue Types> assigned to it in Jira.

=item C<< originalIssueTypeMappings >>

For draft workflow schemes, this property is the issue type to workflow mappings for the original workflow scheme, where each mapping is an issue type ID and workflow name pair. Note that an issue type can only be mapped to one workflow in a workflow scheme.

=item C<< self >>

=item C<< updateDraftIfNeeded >>

Whether to create or update a draft workflow scheme when updating an active workflow scheme. An active workflow scheme is a workflow scheme that is used by at least one project. The following examples show how this property works:

=over

=item *

Update an active workflow scheme with C<updateDraftIfNeeded> set to C<true>: If a draft workflow scheme exists, it is updated. Otherwise, a draft workflow scheme is created.


=item *

Update an active workflow scheme with C<updateDraftIfNeeded> set to C<false>: An error is returned, as active workflow schemes cannot be updated.


=item *

Update an inactive workflow scheme with C<updateDraftIfNeeded> set to C<true>: The workflow scheme is updated, as inactive workflow schemes do not require drafts to update.


=back

Defaults to C<false>.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_updateWorkflowSchemeDraft_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateWorkflowSchemeDraft( $self, %options ) {
    my $tx = $self->_build_updateWorkflowSchemeDraft_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if: * the original active workflow scheme is not found. * the original active workflow scheme does not have a draft.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteDraftDefaultWorkflow >>

  my $res = $client->deleteDraftDefaultWorkflow()->get;

Delete draft default workflow

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_deleteDraftDefaultWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/default' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteDraftDefaultWorkflow( $self, %options ) {
    my $tx = $self->_build_deleteDraftDefaultWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow scheme does not have a draft.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDraftDefaultWorkflow >>

  my $res = $client->getDraftDefaultWorkflow()->get;

Get draft default workflow

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=back


Returns a L<< JIRA::API::DefaultWorkflow >>.

=cut

sub _build_getDraftDefaultWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/default' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDraftDefaultWorkflow( $self, %options ) {
    my $tx = $self->_build_getDraftDefaultWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::DefaultWorkflow->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission..
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow scheme does not have a draft.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateDraftDefaultWorkflow >>

  my $res = $client->updateDraftDefaultWorkflow()->get;

Update draft default workflow

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=back


=head3 Options

=over 4

=item C<< updateDraftIfNeeded >>

Whether a draft workflow scheme is created or updated when updating an active workflow scheme. The draft is updated with the new default workflow. Defaults to C<false>.

=item C<< workflow >>

The name of the workflow to set as the default workflow.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_updateDraftDefaultWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/default' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::DefaultWorkflow->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateDraftDefaultWorkflow( $self, %options ) {
    my $tx = $self->_build_updateDraftDefaultWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow scheme does not have a draft.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowSchemeDraftIssueType >>

  my $res = $client->deleteWorkflowSchemeDraftIssueType()->get;

Delete workflow for issue type in draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< issueType >>

The ID of the issue type.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_deleteWorkflowSchemeDraftIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'issueType'"
        unless exists $options{ 'issueType' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/issuetype/{issueType}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'issueType' => delete $options{'issueType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteWorkflowSchemeDraftIssueType( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowSchemeDraftIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowSchemeDraftIssueType >>

  my $res = $client->getWorkflowSchemeDraftIssueType()->get;

Get workflow for issue type in draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< issueType >>

The ID of the issue type.

=back


Returns a L<< JIRA::API::IssueTypeWorkflowMapping >>.

=cut

sub _build_getWorkflowSchemeDraftIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'issueType'"
        unless exists $options{ 'issueType' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/issuetype/{issueType}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'issueType' => delete $options{'issueType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowSchemeDraftIssueType( $self, %options ) {
    my $tx = $self->_build_getWorkflowSchemeDraftIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeWorkflowMapping->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setWorkflowSchemeDraftIssueType >>

  my $res = $client->setWorkflowSchemeDraftIssueType()->get;

Set workflow for issue type in draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< issueType >>

The ID of the issue type.

=back


=head3 Options

=over 4

=item C<< issueType >>

The ID of the issue type. Not required if updating the issue type-workflow mapping.

=item C<< updateDraftIfNeeded >>

Set to true to create or update the draft of a workflow scheme and update the mapping in the draft, when the workflow scheme cannot be edited. Defaults to C<false>. Only applicable when updating the workflow-issue types mapping.

=item C<< workflow >>

The name of the workflow.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_setWorkflowSchemeDraftIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'issueType'"
        unless exists $options{ 'issueType' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/issuetype/{issueType}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'issueType' => delete $options{'issueType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeWorkflowMapping->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setWorkflowSchemeDraftIssueType( $self, %options ) {
    my $tx = $self->_build_setWorkflowSchemeDraftIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< publishDraftWorkflowScheme >>

  my $res = $client->publishDraftWorkflowScheme()->get;

Publish draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< validateOnly >>

Whether the request only performs a validation.

=back


=head3 Options

=over 4

=item C<< statusMappings >>

Mappings of statuses to new statuses for issue types.

=back

Returns a L<< JIRA::API::TaskProgressBeanObject >>.

=cut

sub _build_publishDraftWorkflowScheme_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'POST';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/publish' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'validateOnly' => delete $options{'validateOnly'},
    );

    my $request = JIRA::API::PublishDraftWorkflowScheme->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub publishDraftWorkflowScheme( $self, %options ) {
    my $tx = $self->_build_publishDraftWorkflowScheme_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is only for validation and is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 303 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::TaskProgressBeanObject->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of these are true: * The workflow scheme is not found. * The workflow scheme does not have a draft. * A new status in the draft workflow scheme is not found.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteDraftWorkflowMapping >>

  my $res = $client->deleteDraftWorkflowMapping()->get;

Delete issue types for workflow in draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< workflowName >>

The name of the workflow.

=back



=cut

sub _build_deleteDraftWorkflowMapping_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/workflow' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'workflowName' => delete $options{'workflowName'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteDraftWorkflowMapping( $self, %options ) {
    my $tx = $self->_build_deleteDraftWorkflowMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow scheme does not have a draft. * The workflow is not found. * The workflow is not specified.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getDraftWorkflow >>

  my $res = $client->getDraftWorkflow()->get;

Get issue types for workflows in draft workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< workflowName >>

The name of a workflow in the scheme. Limits the results to the workflow-issue type mapping for the specified workflow.

=back


Returns a L<< JIRA::API::IssueTypesWorkflowMapping >>.

=cut

sub _build_getDraftWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/workflow' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'workflowName' => delete $options{'workflowName'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getDraftWorkflow( $self, %options ) {
    my $tx = $self->_build_getDraftWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypesWorkflowMapping->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if either the workflow scheme or workflow (if specified) is not found. session.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateDraftWorkflowMapping >>

  my $res = $client->updateDraftWorkflowMapping()->get;

Set issue types for workflow in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme that the draft belongs to.

=item B<< workflowName >>

The name of the workflow.

=back


=head3 Options

=over 4

=item C<< defaultMapping >>

Whether the workflow is the default workflow for the workflow scheme.

=item C<< issueTypes >>

The list of issue type IDs.

=item C<< updateDraftIfNeeded >>

Whether a draft workflow scheme is created or updated when updating an active workflow scheme. The draft is updated with the new workflow-issue types mapping. Defaults to C<false>.

=item C<< workflow >>

The name of the workflow. Optional if updating the workflow-issue types mapping.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_updateDraftWorkflowMapping_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/draft/workflow' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'workflowName' => delete $options{'workflowName'},
    );

    my $request = JIRA::API::IssueTypesWorkflowMapping->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateDraftWorkflowMapping( $self, %options ) {
    my $tx = $self->_build_updateDraftWorkflowMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow scheme does not have a draft. * The workflow is not found. * The workflow is not specified.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowSchemeIssueType >>

  my $res = $client->deleteWorkflowSchemeIssueType()->get;

Delete workflow for issue type in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< issueType >>

The ID of the issue type.

=item B<< updateDraftIfNeeded >>

Set to true to create or update the draft of a workflow scheme and update the mapping in the draft, when the workflow scheme cannot be edited. Defaults to C<false>.

=back


Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_deleteWorkflowSchemeIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'issueType'"
        unless exists $options{ 'issueType' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/issuetype/{issueType}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'issueType' => delete $options{'issueType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'updateDraftIfNeeded' => delete $options{'updateDraftIfNeeded'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub deleteWorkflowSchemeIssueType( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowSchemeIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the workflow cannot be edited and `updateDraftIfNeeded` is false.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflowSchemeIssueType >>

  my $res = $client->getWorkflowSchemeIssueType()->get;

Get workflow for issue type in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< issueType >>

The ID of the issue type.

=item B<< returnDraftIfExists >>

Returns the mapping from the workflow scheme's draft rather than the workflow scheme, if set to true. If no draft exists, the mapping from the workflow scheme is returned.

=back


Returns a L<< JIRA::API::IssueTypeWorkflowMapping >>.

=cut

sub _build_getWorkflowSchemeIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'issueType'"
        unless exists $options{ 'issueType' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/issuetype/{issueType}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'issueType' => delete $options{'issueType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'returnDraftIfExists' => delete $options{'returnDraftIfExists'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflowSchemeIssueType( $self, %options ) {
    my $tx = $self->_build_getWorkflowSchemeIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypeWorkflowMapping->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< setWorkflowSchemeIssueType >>

  my $res = $client->setWorkflowSchemeIssueType()->get;

Set workflow for issue type in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< issueType >>

The ID of the issue type.

=back


=head3 Options

=over 4

=item C<< issueType >>

The ID of the issue type. Not required if updating the issue type-workflow mapping.

=item C<< updateDraftIfNeeded >>

Set to true to create or update the draft of a workflow scheme and update the mapping in the draft, when the workflow scheme cannot be edited. Defaults to C<false>. Only applicable when updating the workflow-issue types mapping.

=item C<< workflow >>

The name of the workflow.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_setWorkflowSchemeIssueType_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'issueType'"
        unless exists $options{ 'issueType' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/issuetype/{issueType}' );
    my $path = $template->process(
              'id' => delete $options{'id'},
              'issueType' => delete $options{'issueType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::IssueTypeWorkflowMapping->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub setWorkflowSchemeIssueType( $self, %options ) {
    my $tx = $self->_build_setWorkflowSchemeIssueType_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the workflow cannot be edited and `updateDraftIfNeeded` is false.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if the workflow scheme or issue type is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< deleteWorkflowMapping >>

  my $res = $client->deleteWorkflowMapping()->get;

Delete issue types for workflow in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< workflowName >>

The name of the workflow.

=item B<< updateDraftIfNeeded >>

Set to true to create or update the draft of a workflow scheme and delete the mapping from the draft, when the workflow scheme cannot be edited. Defaults to C<false>.

=back



=cut

sub _build_deleteWorkflowMapping_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/workflow' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'workflowName' => delete $options{'workflowName'},
        maybe 'updateDraftIfNeeded' => delete $options{'updateDraftIfNeeded'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
        }
    );

    return $tx
}


sub deleteWorkflowMapping( $self, %options ) {
    my $tx = $self->_build_deleteWorkflowMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the workflow cannot be edited and `updateDraftIfNeeded` is not true.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow is not found. * The workflow is not specified.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorkflow >>

  my $res = $client->getWorkflow()->get;

Get issue types for workflows in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< workflowName >>

The name of a workflow in the scheme. Limits the results to the workflow-issue type mapping for the specified workflow.

=item B<< returnDraftIfExists >>

Returns the mapping from the workflow scheme's draft rather than the workflow scheme, if set to true. If no draft exists, the mapping from the workflow scheme is returned.

=back


Returns a L<< JIRA::API::IssueTypesWorkflowMapping >>.

=cut

sub _build_getWorkflow_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/workflow' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'workflowName' => delete $options{'workflowName'},
        maybe 'returnDraftIfExists' => delete $options{'returnDraftIfExists'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getWorkflow( $self, %options ) {
    my $tx = $self->_build_getWorkflow_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::IssueTypesWorkflowMapping->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if either the workflow scheme or workflow is not found.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< updateWorkflowMapping >>

  my $res = $client->updateWorkflowMapping()->get;

Set issue types for workflow in workflow scheme

=head3 Parameters

=over 4

=item B<< id >>

The ID of the workflow scheme.

=item B<< workflowName >>

The name of the workflow.

=back


=head3 Options

=over 4

=item C<< defaultMapping >>

Whether the workflow is the default workflow for the workflow scheme.

=item C<< issueTypes >>

The list of issue type IDs.

=item C<< updateDraftIfNeeded >>

Whether a draft workflow scheme is created or updated when updating an active workflow scheme. The draft is updated with the new workflow-issue types mapping. Defaults to C<false>.

=item C<< workflow >>

The name of the workflow. Optional if updating the workflow-issue types mapping.

=back

Returns a L<< JIRA::API::WorkflowScheme >>.

=cut

sub _build_updateWorkflowMapping_request( $self, %options ) {
    croak "Missing required parameter 'id'"
        unless exists $options{ 'id' };
    croak "Missing required parameter 'workflowName'"
        unless exists $options{ 'workflowName' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/api/3/workflowscheme/{id}/workflow' );
    my $path = $template->process(
              'id' => delete $options{'id'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
              'workflowName' => delete $options{'workflowName'},
    );

    my $request = JIRA::API::IssueTypesWorkflowMapping->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub updateWorkflowMapping( $self, %options ) {
    my $tx = $self->_build_updateWorkflowMapping_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowScheme->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the user does not have the necessary permission.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 404 ) {
            # Returned if any of the following is true: * The workflow scheme is not found. * The workflow is not found. * The workflow is not specified.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIdsOfWorklogsDeletedSince >>

  my $res = $client->getIdsOfWorklogsDeletedSince()->get;

Get IDs of deleted worklogs

=head3 Parameters

=over 4

=item B<< since >>

The date and time, as a UNIX timestamp in milliseconds, after which deleted worklogs are returned.

=back


Returns a L<< JIRA::API::ChangedWorklogs >>.

=cut

sub _build_getIdsOfWorklogsDeletedSince_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/worklog/deleted';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'since' => delete $options{'since'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIdsOfWorklogsDeletedSince( $self, %options ) {
    my $tx = $self->_build_getIdsOfWorklogsDeletedSince_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ChangedWorklogs->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getWorklogsForIds >>

  my $res = $client->getWorklogsForIds()->get;

Get worklogs

=head3 Parameters

=over 4

=item B<< expand >>

Use L<expand|#expansion> to include additional information about worklogs in the response. This parameter accepts C<properties> that returns the properties of each worklog.

=back


=head3 Options

=over 4

=item C<< ids >>

A list of worklog IDs.

=back

Returns an array of L<< JIRA::API::Worklog >>.

=cut

sub _build_getWorklogsForIds_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/api/3/worklog/list';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'expand' => delete $options{'expand'},
    );

    my $request = JIRA::API::WorklogIdsRequestBean->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub getWorklogsForIds( $self, %options ) {
    my $tx = $self->_build_getWorklogsForIds_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    [ map { JIRA::API::Worklog->new($_),
 } $payload->@* ],

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request contains more than 1000 worklog IDs or is empty.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< getIdsOfWorklogsModifiedSince >>

  my $res = $client->getIdsOfWorklogsModifiedSince()->get;

Get IDs of updated worklogs

=head3 Parameters

=over 4

=item B<< since >>

The date and time, as a UNIX timestamp in milliseconds, after which updated worklogs are returned.

=item B<< expand >>

Use L<expand|#expansion> to include additional information about worklogs in the response. This parameter accepts C<properties> that returns the properties of each worklog.

=back


Returns a L<< JIRA::API::ChangedWorklogs >>.

=cut

sub _build_getIdsOfWorklogsModifiedSince_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/api/3/worklog/updated';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'since' => delete $options{'since'},
        maybe 'expand' => delete $options{'expand'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub getIdsOfWorklogsModifiedSince( $self, %options ) {
    my $tx = $self->_build_getIdsOfWorklogsModifiedSince_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ChangedWorklogs->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< AddonPropertiesResource_getAddonProperties_get >>

  my $res = $client->AddonPropertiesResource_getAddonProperties_get()->get;

Get app properties

=head3 Parameters

=over 4

=item B<< addonKey >>

The key of the app, as defined in its descriptor.

=back


Returns a L<< JIRA::API::PropertyKeys >>.
Returns a L<< JIRA::API::OperationMessage >>.

=cut

sub _build_AddonPropertiesResource_getAddonProperties_get_request( $self, %options ) {
    croak "Missing required parameter 'addonKey'"
        unless exists $options{ 'addonKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/atlassian-connect/1/addons/{addonKey}/properties' );
    my $path = $template->process(
              'addonKey' => delete $options{'addonKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub AddonPropertiesResource_getAddonProperties_get( $self, %options ) {
    my $tx = $self->_build_AddonPropertiesResource_getAddonProperties_get_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::PropertyKeys->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< AddonPropertiesResource_deleteAddonProperty_delete >>

  my $res = $client->AddonPropertiesResource_deleteAddonProperty_delete()->get;

Delete app property

=head3 Parameters

=over 4

=item B<< addonKey >>

The key of the app, as defined in its descriptor.

=item B<< propertyKey >>

The key of the property.

=back


Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.

=cut

sub _build_AddonPropertiesResource_deleteAddonProperty_delete_request( $self, %options ) {
    croak "Missing required parameter 'addonKey'"
        unless exists $options{ 'addonKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'DELETE';
    my $template = URI::Template->new( '/rest/atlassian-connect/1/addons/{addonKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'addonKey' => delete $options{'addonKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub AddonPropertiesResource_deleteAddonProperty_delete( $self, %options ) {
    my $tx = $self->_build_AddonPropertiesResource_deleteAddonProperty_delete_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the property key is longer than 127 characters.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the property is not found or doesn't belong to the app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< AddonPropertiesResource_getAddonProperty_get >>

  my $res = $client->AddonPropertiesResource_getAddonProperty_get()->get;

Get app property

=head3 Parameters

=over 4

=item B<< addonKey >>

The key of the app, as defined in its descriptor.

=item B<< propertyKey >>

The key of the property.

=back


Returns a L<< JIRA::API::EntityProperty >>.
Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.

=cut

sub _build_AddonPropertiesResource_getAddonProperty_get_request( $self, %options ) {
    croak "Missing required parameter 'addonKey'"
        unless exists $options{ 'addonKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'GET';
    my $template = URI::Template->new( '/rest/atlassian-connect/1/addons/{addonKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'addonKey' => delete $options{'addonKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub AddonPropertiesResource_getAddonProperty_get( $self, %options ) {
    my $tx = $self->_build_AddonPropertiesResource_getAddonProperty_get_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::EntityProperty->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the property key is longer than 127 characters.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 404 ) {
            # Returned if the property is not found or doesn't belong to the app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< AddonPropertiesResource_putAddonProperty_put >>

  my $res = $client->AddonPropertiesResource_putAddonProperty_put()->get;

Set app property

=head3 Parameters

=over 4

=item B<< addonKey >>

The key of the app, as defined in its descriptor.

=item B<< propertyKey >>

The key of the property.

=back


Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.
Returns a L<< JIRA::API::OperationMessage >>.

=cut

sub _build_AddonPropertiesResource_putAddonProperty_put_request( $self, %options ) {
    croak "Missing required parameter 'addonKey'"
        unless exists $options{ 'addonKey' };
    croak "Missing required parameter 'propertyKey'"
        unless exists $options{ 'propertyKey' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/atlassian-connect/1/addons/{addonKey}/properties/{propertyKey}' );
    my $path = $template->process(
              'addonKey' => delete $options{'addonKey'},
              'propertyKey' => delete $options{'propertyKey'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub AddonPropertiesResource_putAddonProperty_put( $self, %options ) {
    my $tx = $self->_build_AddonPropertiesResource_putAddonProperty_put_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the property is updated.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 201 ) {
            # Returned is the property is created.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if: * the property key is longer than 127 characters. * the value is not valid JSON. * the value is longer than 32768 characters.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the authentication credentials are incorrect or missing.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::OperationMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< DynamicModulesResource_removeModules_delete >>

  my $res = $client->DynamicModulesResource_removeModules_delete()->get;

Remove modules

=head3 Parameters

=over 4

=item B<< moduleKey >>

The key of the module to remove. To include multiple module keys, provide multiple copies of this parameter.
For example, C<moduleKey=dynamic-attachment-entity-property&moduleKey=dynamic-select-field>.
Nonexistent keys are ignored.

=back


Returns a L<< JIRA::API::ErrorMessage >>.

=cut

sub _build_DynamicModulesResource_removeModules_delete_request( $self, %options ) {
    my $method = 'DELETE';
    my $path = '/rest/atlassian-connect/1/app/module/dynamic';
    my $url = Mojo::URL->new( $self->server . $path );

    $url->query->merge(
        maybe 'moduleKey' => delete $options{'moduleKey'},
    );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub DynamicModulesResource_removeModules_delete( $self, %options ) {
    my $tx = $self->_build_DynamicModulesResource_removeModules_delete_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 204 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 401 ) {
            # Returned if the call is not from a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< DynamicModulesResource_getModules_get >>

  my $res = $client->DynamicModulesResource_getModules_get()->get;

Get modules

=head3 Parameters

=over 4

=back


Returns a L<< JIRA::API::ConnectModules >>.
Returns a L<< JIRA::API::ErrorMessage >>.

=cut

sub _build_DynamicModulesResource_getModules_get_request( $self, %options ) {
    my $method = 'GET';
    my $path = '/rest/atlassian-connect/1/app/module/dynamic';
    my $url = Mojo::URL->new( $self->server . $path );

    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
        }
    );

    return $tx
}


sub DynamicModulesResource_getModules_get( $self, %options ) {
    my $tx = $self->_build_DynamicModulesResource_getModules_get_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ConnectModules->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the call is not from a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< DynamicModulesResource_registerModules_post >>

  my $res = $client->DynamicModulesResource_registerModules_post()->get;

Register modules

=head3 Parameters

=over 4

=back


=head3 Options

=over 4

=item C<< modules >>

A list of app modules in the same format as the C<modules> property in the
L<app descriptor|https://developer.atlassian.com/cloud/jira/platform/app-descriptor/>.

=back

Returns a L<< JIRA::API::ErrorMessage >>.
Returns a L<< JIRA::API::ErrorMessage >>.

=cut

sub _build_DynamicModulesResource_registerModules_post_request( $self, %options ) {
    my $method = 'POST';
    my $path = '/rest/atlassian-connect/1/app/module/dynamic';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ConnectModules->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub DynamicModulesResource_registerModules_post( $self, %options ) {
    my $tx = $self->_build_DynamicModulesResource_registerModules_post_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if: * any of the provided modules is invalid. For example, required properties are missing. * any of the modules conflict with registered dynamic modules or modules defined in the app descriptor. For example, there are duplicate keys. Details of the issues encountered are included in the error message.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorMessage->new($payload),

                );
            }
        } elsif( $resp->code == 401 ) {
            # Returned if the call is not from a Connect app.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::ErrorMessage->new($payload),

                );
            }
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< AppIssueFieldValueUpdateResource_updateIssueFields_put >>

  my $res = $client->AppIssueFieldValueUpdateResource_updateIssueFields_put()->get;

Bulk update custom field value

=head3 Parameters

=over 4

=item B<< Atlassian-Transfer-Id >>

The ID of the transfer.

=back


=head3 Options

=over 4

=item C<< updateValueList >>

The list of custom field update details.

=back

Returns a L<<  >>.

=cut

sub _build_AppIssueFieldValueUpdateResource_updateIssueFields_put_request( $self, %options ) {
    croak "Missing required parameter 'Atlassian-Transfer-Id'"
        unless exists $options{ 'Atlassian-Transfer-Id' };

    my $method = 'PUT';
    my $path = '/rest/atlassian-connect/1/migration/field';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::ConnectCustomFieldValues->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
                   'Atlassian-Transfer-Id' => delete $options{'Atlassian-Transfer-Id'}
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub AppIssueFieldValueUpdateResource_updateIssueFields_put( $self, %options ) {
    my $tx = $self->_build_AppIssueFieldValueUpdateResource_updateIssueFields_put_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    $payload

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is invalid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if: * the transfer ID is not found. * the authorisation credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< MigrationResource_updateEntityPropertiesValue_put >>

  my $res = $client->MigrationResource_updateEntityPropertiesValue_put()->get;

Bulk update entity properties

=head3 Parameters

=over 4

=item B<< Atlassian-Transfer-Id >>

The app migration transfer ID.

=item B<< entityType >>

The type indicating the object that contains the entity properties.

=back



=cut

sub _build_MigrationResource_updateEntityPropertiesValue_put_request( $self, %options ) {
    croak "Missing required parameter 'Atlassian-Transfer-Id'"
        unless exists $options{ 'Atlassian-Transfer-Id' };
    croak "Missing required parameter 'entityType'"
        unless exists $options{ 'entityType' };

    my $method = 'PUT';
    my $template = URI::Template->new( '/rest/atlassian-connect/1/migration/properties/{entityType}' );
    my $path = $template->process(
              'entityType' => delete $options{'entityType'},
    );
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            "Content-Type" => 'application/json',
                   'Atlassian-Transfer-Id' => delete $options{'Atlassian-Transfer-Id'}
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub MigrationResource_updateEntityPropertiesValue_put( $self, %options ) {
    my $tx = $self->_build_MigrationResource_updateEntityPropertiesValue_put_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the authorisation credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}

=head2 C<< MigrationResource_workflowRuleSearch_post >>

  my $res = $client->MigrationResource_workflowRuleSearch_post()->get;

Get workflow transition rule configurations

=head3 Parameters

=over 4

=item B<< Atlassian-Transfer-Id >>

The app migration transfer ID.

=back


=head3 Options

=over 4

=item C<< expand >>

Use expand to include additional information in the response. This parameter accepts C<transition> which, for each rule, returns information about the transition the rule is assigned to.

=item C<< ruleIds >>

The list of workflow rule IDs.

=item C<< workflowEntityId >>

The workflow ID.

=back

Returns a L<< JIRA::API::WorkflowRulesSearchDetails >>.

=cut

sub _build_MigrationResource_workflowRuleSearch_post_request( $self, %options ) {
    croak "Missing required parameter 'Atlassian-Transfer-Id'"
        unless exists $options{ 'Atlassian-Transfer-Id' };

    my $method = 'POST';
    my $path = '/rest/atlassian-connect/1/migration/workflow/rule/search';
    my $url = Mojo::URL->new( $self->server . $path );

    my $request = JIRA::API::WorkflowRulesSearch->new( \%options );
    my $tx = $self->ua->build_tx(
        $method => $url,
        {
            'Accept' => 'application/json',
            "Content-Type" => 'application/json',
                   'Atlassian-Transfer-Id' => delete $options{'Atlassian-Transfer-Id'}
        }
        => json => $request->as_hash,
    );

    return $tx
}


sub MigrationResource_workflowRuleSearch_post( $self, %options ) {
    my $tx = $self->_build_MigrationResource_workflowRuleSearch_post_request(%options);

    # validate our request while developing
    my $results = $self->openapi->validate_request($tx->req);
    if( $results->{error}) {
        say $results;
        say $tx->req->to_string;
    };


    my $r1 = Future::Mojo->new();
    my $res = $r1->then( sub( $tx ) {
        my $resp = $tx->res;
        # Should we validate using OpenAPI::Modern here?!
        if( $resp->code == 200 ) {
            # Returned if the request is successful.
            my $ct = $resp->headers->content_type;
            $ct =~ s/;\s+.*//;
            if( $ct eq 'application/json' ) {
                my $payload = $resp->json();
                return Future::Mojo->done(
                    JIRA::API::WorkflowRulesSearchDetails->new($payload),

                );
            }
        } elsif( $resp->code == 400 ) {
            # Returned if the request is not valid.
            return Future::Mojo->done($resp);
        } elsif( $resp->code == 403 ) {
            # Returned if the authorisation credentials are incorrect or missing.
            return Future::Mojo->done($resp);
        } else {
            # An unknown/unhandled response, likely an error
            return Future::Mojo->fail($resp);
        }
    });

    # Start our transaction
    $tx = $self->ua->start_p($tx)->then(sub($tx) {
        $r1->resolve( $tx );
        undef $r1;
    })->catch(sub($err) {
        $r1->fail( $err => $tx );
        undef $r1;
    });

    return $res
}


1;
