Repository: ctreminiom/go-atlassian
Pull request #230 (2023-07-30 05:16:00)

:sparkles: Extract customfields from buffer support
…an array of issues.


Patch:
diff --git a/pkg/infra/models/agile_sprint.go b/pkg/infra/models/agile_sprint.go
index 520a800..1e0ca09 100644
--- a/pkg/infra/models/agile_sprint.go
+++ b/pkg/infra/models/agile_sprint.go
@@ -54,4 +54,5 @@ type SprintDetailScheme struct {
 	CompleteDate  string `json:"completeDate,omitempty"`
 	OriginBoardID int    `json:"originBoardId,omitempty"`
 	Goal          string `json:"goal,omitempty"`
+	BoardID       int    `json:"boardId,omitempty"`
 }
diff --git a/pkg/infra/models/errors.go b/pkg/infra/models/errors.go
index 0cce13e..7e27230 100644
--- a/pkg/infra/models/errors.go
+++ b/pkg/infra/models/errors.go
@@ -138,6 +138,10 @@ var (
 	ErrUnauthorized                        = errors.New("client: atlassian insufficient permissions")
 	ErrInternalError                       = errors.New("client: atlassian internal error")
 	ErrBadRequestError                     = errors.New("client: atlassian invalid payload")
+	ErrNoSiteError                         = errors.New("client: no atlassian site set")
+	ErrNoFloatTypeError                    = errors.New("custom-field: no float type set")
+	ErrNoSprintTypeError                   = errors.New("custom-field: no sprint type found")
+	ErrNoMultiVersionTypeError             = errors.New("custom-field: no multiversion type found")
 	ErrNilPayloadError                     = errors.New("client: please provide the necessary payload struct")
 	ErrNonPayloadPointerError              = errors.New("client: please provide a valid payload struct pointer (&)")
 	ErrNoFieldInformationError             = errors.New("custom-field: please provide a buffer with a valid fields object")
@@ -146,11 +150,12 @@ var (
 	ErrNoAssetTypeError                    = errors.New("custom-field: no asset type found")
 	ErrNoUrlTypeError                      = errors.New("custom-field: no url type set")
 	ErrNoTextTypeError                     = errors.New("custom-field: no text type set")
-	ErrNoDateTimeTypeError                 = errors.New("custom-field: no date-time type set")
-	ErrNoDateTypeError                     = errors.New("custom-field: no date type set")
+	ErrNoDatePickerTypeError               = errors.New("custom-field: no datepicker type set")
+	ErrNoDateTimeTypeError                 = errors.New("custom-field: no datetime type set")
 	ErrNoSelectTypeError                   = errors.New("custom-field: no select type set")
 	ErrNoButtonTypeError                   = errors.New("custom-field: no button type set")
 	ErrNoUserTypeError                     = errors.New("custom-field: no user type set")
+	ErrNoLabelsTypeError                   = errors.New("custom-field: no labels type set")
 	ErrNoMultiUserTypeError                = errors.New("custom-field: no multi-user type set")
 	ErrNoCheckBoxTypeError                 = errors.New("custom-field: no check-box type set")
 	ErrNoCascadingParentError              = errors.New("custom-field: no cascading parent value set")
@@ -158,6 +163,8 @@ var (
 	ErrNoAttachmentIdsError                = errors.New("sm: no attachment id's set")
 	ErrNoLabelsError                       = errors.New("sm: no label names set")
 	ErrNoComponentsError                   = errors.New("sm: no components set")
+	ErrNoIssuesSliceError                  = errors.New("jira: no issues object set")
+	ErrNoMapValuesError                    = errors.New("jira: no map values set")
 	ErrNCoComponentError                   = errors.New("sm: no component set")
 	ErrNoWorkspaceIDError                  = errors.New("assets: no workspace id set")
 	ErrNoAqlQueryError                     = errors.New("assets: no aql query id set")
@@ -166,12 +173,10 @@ var (
 	ErrNoObjectSchemaIDError               = errors.New("assets: no object schema id set")
 	ErrNoObjectTypeIDError                 = errors.New("assets: no object type id set")
 	ErrNoObjectTypeAttributeIDError        = errors.New("assets: no object type attribute id set")
-	ErrNoSiteError                         = errors.New("client: no atlassian site set")
 	ErrNoCreateIssuesError                 = errors.New("jira: no issues payload set")
 	ErrNoIssueSchemeError                  = errors.New("jira: no issue instance set")
-
-	ErrNoWorkspaceError  = errors.New("bitbucket: no workspace set")
-	ErrNoMemberIDError   = errors.New("bitbucket: no member id set")
-	ErrNoWebhookIDError  = errors.New("bitbucket: no webhook id set")
-	ErrNoRepositoryError = errors.New("bitbucket: no repository set")
+	ErrNoWorkspaceError                    = errors.New("bitbucket: no workspace set")
+	ErrNoMemberIDError                     = errors.New("bitbucket: no member id set")
+	ErrNoWebhookIDError                    = errors.New("bitbucket: no webhook id set")
+	ErrNoRepositoryError                   = errors.New("bitbucket: no repository set")
 )
diff --git a/pkg/infra/models/jira_customFields.go b/pkg/infra/models/jira_customFields.go
index a02d04c..83cd5c5 100644
--- a/pkg/infra/models/jira_customFields.go
+++ b/pkg/infra/models/jira_customFields.go
@@ -105,7 +105,7 @@ func (c *CustomFields) DateTime(customFieldID string, dateValue time.Time) error
 	}
 
 	if dateValue.IsZero() {
-		return ErrNoDateTimeTypeError
+		return ErrNoDatePickerTypeError
 	}
 
 	var dateNode = map[string]interface{}{}
@@ -125,7 +125,7 @@ func (c *CustomFields) Date(customFieldID string, dateTimeValue time.Time) (err
 	}
 
 	if dateTimeValue.IsZero() {
-		return ErrNoDateTypeError
+		return ErrNoDateTimeTypeError
 	}
 
 	var dateTimeNode = map[string]interface{}{}
diff --git a/pkg/infra/models/jira_issue_custom_fields.go b/pkg/infra/models/jira_issue_custom_fields.go
index 751fdc8..f895ae3 100644
--- a/pkg/infra/models/jira_issue_custom_fields.go
+++ b/pkg/infra/models/jira_issue_custom_fields.go
@@ -2,460 +2,1819 @@ package models
 
 import (
 	"bytes"
-
-	"github.com/perimeterx/marshmallow"
+	"encoding/json"
+	"fmt"
+	"github.com/tidwall/gjson"
+	"reflect"
+	"time"
 )
 
+// ParseMultiSelectCustomField parses a multi-select custom field from the given buffer data
+// associated with the specified custom field ID and returns a slice of pointers to
+// CustomFieldContextOptionSchema structs.
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - []*CustomFieldContextOptionSchema: A slice of pointers to CustomFieldContextOptionSchema
+//     structs representing the parsed options associated with the custom field.
+//
+// The ParseMultiSelectCustomField method is responsible for extracting and parsing the
+// serialized data from the provided buffer, which is expected to be in a specific format.
+// It then constructs and returns a slice of pointers to CustomFieldContextOptionSchema
+// structs that represent the parsed options for the given custom field.
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	options, err := ParseMultiSelectCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//	for _, option := range options {
+//	    fmt.Printf("Option ID: %s, Option Name: %s\n", option.ID, option.Name)
+//	}
+//
+// NOTE: This method can be used to extract check-box customfield values
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-multiselect-customfield
 func ParseMultiSelectCustomField(buffer bytes.Buffer, customField string) ([]*CustomFieldContextOptionScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var records []*CustomFieldContextOptionScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoMultiSelectTypeError
+	}
+
+	var options []*CustomFieldContextOptionScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &options); err != nil {
+		return nil, ErrNoMultiSelectTypeError
+	}
 
-	switch options := customFields[customField].(type) {
-	case []interface{}:
+	return options, nil
+}
 
-		for _, option := range options {
+// ParseMultiSelectCustomFields extracts and parses multi-select custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a slice of CustomFieldContextOptionScheme
+// structs, representing the parsed multi-select custom field values.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseMultiSelectCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, value := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", value)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string][]*CustomFieldContextOptionScheme: A map where the key is the issue key and the
+//     value is a slice of CustomFieldContextOptionScheme structs representing the parsed
+//     multi-select custom field values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-multiselect-customfields
+func ParseMultiSelectCustomFields(buffer bytes.Buffer, customField string) (map[string][]*CustomFieldContextOptionScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-			record := &CustomFieldContextOptionScheme{
-				ID:    option.(map[string]interface{})["id"].(string),
-				Value: option.(map[string]interface{})["value"].(string),
-			}
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]*CustomFieldContextOptionScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
 
-			isDisabled, wasFound := option.(map[string]interface{})["disabled"].(bool)
-			if wasFound {
-				record.Disabled = isDisabled
-			}
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
 
-			optionID, wasFound := option.(map[string]interface{})["optionId"].(string)
-			if wasFound {
-				record.OptionID = optionID
-			}
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
 
-			records = append(records, record)
+		var customFields []*CustomFieldContextOptionScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return records, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseMultiGroupPickerCustomField parses a group-picker custom field from the given buffer data
+// associated with the specified custom field ID and returns a slice of pointers to
+// GroupDetailScheme structs.
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - []*GroupDetailScheme: A slice of pointers to GroupDetailScheme
+//     structs representing the parsed group picker associated with the custom field.
+//
+// The GroupDetailScheme method is responsible for extracting and parsing the
+// serialized data from the provided buffer, which is expected to be in a specific format.
+// It then constructs and returns a slice of pointers to GroupDetailScheme
+// structs that represent the parsed groups for the given custom field.
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	groups, err := ParseMultiGroupPickerCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//	for _, group := range groups {
+//	    fmt.Printf("Group ID: %s, Group Name: %s\n", group.GroupID, group.Name)
+//	}
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-grouppicker-customfield
 func ParseMultiGroupPickerCustomField(buffer bytes.Buffer, customField string) ([]*GroupDetailScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var groups []*GroupDetailScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoMultiSelectTypeError
+	}
 
-	switch options := customFields[customField].(type) {
-	case []interface{}:
+	var options []*GroupDetailScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &options); err != nil {
+		return nil, ErrNoMultiSelectTypeError
+	}
 
-		for _, option := range options {
+	return options, nil
+}
 
-			group := &GroupDetailScheme{
-				Self:    option.(map[string]interface{})["self"].(string),
-				Name:    option.(map[string]interface{})["name"].(string),
-				GroupID: option.(map[string]interface{})["groupId"].(string),
-			}
+// ParseMultiGroupPickerCustomFields extracts and parses a group picker custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a slice of GroupDetailScheme
+// structs, representing the parsed multi-select custom field values.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseMultiGroupPickerCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, group := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", group)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string][]*GroupDetailScheme: A map where the key is the issue key and the
+//     value is a slice of GroupDetailScheme structs representing the parsed
+//     multi-select custom field values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-grouppicker-customfields
+func ParseMultiGroupPickerCustomFields(buffer bytes.Buffer, customField string) (map[string][]*GroupDetailScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-			groups = append(groups, group)
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]*GroupDetailScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		var customFields []*GroupDetailScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return groups, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseMultiUserPickerCustomField parses a group-picker custom field from the given buffer data
+// associated with the specified custom field ID and returns a slice of pointers to
+// UserDetailScheme structs.
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - []*UserDetailScheme: A slice of pointers to UserDetailScheme
+//     structs representing the parsed user picker associated with the custom field.
+//
+// The UserDetailScheme method is responsible for extracting and parsing the
+// serialized data from the provided buffer, which is expected to be in a specific format.
+// It then constructs and returns a slice of pointers to UserDetailScheme
+// structs that represent the parsed groups for the given custom field.
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	users, err := ParseMultiUserPickerCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//	for _, user := range users {
+//	    fmt.Printf("User ID: %s, User Name: %s\n", user.AccountID, user.DisplayName)
+//	}
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-multi-userpicker-customfield
 func ParseMultiUserPickerCustomField(buffer bytes.Buffer, customField string) ([]*UserDetailScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoMultiSelectTypeError
+	}
+
 	var users []*UserDetailScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &users); err != nil {
+		return nil, ErrNoMultiSelectTypeError
+	}
 
-	switch options := customFields[customField].(type) {
-	case []interface{}:
+	return users, nil
+}
+
+// ParseMultiUserPickerCustomFields extracts and parses a user picker custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a slice of UserDetailScheme
+// structs, representing the parsed multi-select custom field values.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseMultiUserPickerCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, user := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", user)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string][]*UserDetailScheme: A map where the key is the issue key and the
+//     value is a slice of UserDetailScheme structs representing the parsed
+//     multi-select custom field values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-multi-userpicker-customfields
+func ParseMultiUserPickerCustomFields(buffer bytes.Buffer, customField string) (map[string][]*UserDetailScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-		for _, option := range options {
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]*UserDetailScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
 
-			user := &UserDetailScheme{
-				Self:        option.(map[string]interface{})["self"].(string),
-				AccountID:   option.(map[string]interface{})["accountId"].(string),
-				AccountType: option.(map[string]interface{})["accountType"].(string),
-				DisplayName: option.(map[string]interface{})["displayName"].(string),
-				Active:      option.(map[string]interface{})["active"].(bool),
-				TimeZone:    option.(map[string]interface{})["timeZone"].(string),
-			}
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
 
-			email, wasFound := option.(map[string]interface{})["emailAddress"].(string)
-			if wasFound {
-				user.EmailAddress = email
-			}
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
 
-			users = append(users, user)
+		var customFields []*UserDetailScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return users, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseCascadingSelectCustomField parses a cascading custom field from the given buffer data
+// associated with the specified custom field ID and returns a CascadingSelectScheme struct pointer.
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - *CascadingSelectScheme: A pointer of the struct CascadingSelectScheme
+//     representing the parsed cascading data associated with the custom field.
+//
+// The CascadingSelectScheme method is responsible for extracting and parsing the
+// serialized data from the provided buffer, which is expected to be in a specific format.
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	field, err := ParseCascadingSelectCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+//	for _, user := range users {
+//	    fmt.Printf("Parent Value: %s, Child Value: %s\n", field.Value, field.Child.Value)
+//	}
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-cascading-customfield
 func ParseCascadingSelectCustomField(buffer bytes.Buffer, customField string) (*CascadingSelectScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var cascading *CascadingSelectScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoCascadingParentError
+	}
 
-	switch option := customFields[customField].(type) {
-	case map[string]interface{}:
+	var cascading CascadingSelectScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &cascading); err != nil {
+		return nil, ErrNoCascadingParentError
+	}
 
-		cascading = &CascadingSelectScheme{
-			Self:  option["self"].(string),
-			Value: option["value"].(string),
-			Id:    option["id"].(string),
-			Child: &CascadingSelectChildScheme{
-				Self:  option["child"].(map[string]interface{})["self"].(string),
-				Value: option["child"].(map[string]interface{})["value"].(string),
-				Id:    option["child"].(map[string]interface{})["id"].(string),
-			},
-		}
+	return &cascading, nil
+}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+// ParseCascadingCustomFields extracts and parses a cascading custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a CascadingSelectScheme struct pointer
+// ,representing the parsed cascading custom field value.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseCascadingCustomFields (customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, data := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", data)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]*CascadingSelectScheme: A map where the key is the issue key and the
+//     value is a CascadingSelectScheme struct pointer representing the parsed
+//     cascading custom field value.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-cascading-customfields
+func ParseCascadingCustomFields(buffer bytes.Buffer, customField string) (map[string]*CascadingSelectScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
 	}
 
-	return cascading, nil
-}
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]*CascadingSelectScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
 
-func ParseMultiCheckboxesCustomField(buffer bytes.Buffer, customField string) ([]*CustomFieldContextOptionScheme, error) {
-	return ParseMultiSelectCustomField(buffer, customField)
+		var customFields *CascadingSelectScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
+	}
+
+	return customfieldsAsMap, nil
 }
 
+// ParseMultiVersionCustomField parses a version-picker custom field from the given buffer data
+// associated with the specified custom field ID and returns a slice of pointers to
+// VersionDetailScheme structs.
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - []*VersionDetailScheme: A slice of pointers to VersionDetailScheme
+//     structs representing the parsed group picker associated with the custom field.
+//
+// The VersionDetailScheme method is responsible for extracting and parsing the
+// serialized data from the provided buffer, which is expected to be in a specific format.
+// It then constructs and returns a slice of pointers to VersionDetailScheme
+// structs that represent the parsed groups for the given custom field.
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	versions, err := ParseMultiVersionCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//	for _, version := range versions {
+//	    fmt.Printf("Version ID: %s, Version Name: %s\n", version.ID, version.Name)
+//	}
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-versionpicker-customfield
 func ParseMultiVersionCustomField(buffer bytes.Buffer, customField string) ([]*VersionDetailScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var records []*VersionDetailScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoMultiVersionTypeError
+	}
+
+	var versions []*VersionDetailScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &versions); err != nil {
+		return nil, ErrNoMultiSelectTypeError
+	}
 
-	switch options := customFields[customField].(type) {
-	case []interface{}:
+	return versions, nil
+}
+
+// ParseMultiVersionCustomFields extracts and parses a version picker custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a slice of VersionDetailScheme
+// structs, representing the parsed multi-version custom field values.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseMultiVersionCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, version := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", version)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string][]*VersionDetailScheme: A map where the key is the issue key and the
+//     value is a slice of VersionDetailScheme structs representing the parsed
+//     multi-select custom field values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-versionpicker-customfields
+func ParseMultiVersionCustomFields(buffer bytes.Buffer, customField string) (map[string][]*VersionDetailScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-		for _, option := range options {
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]*VersionDetailScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
 
-			record := &VersionDetailScheme{
-				Self:        option.(map[string]interface{})["self"].(string),
-				ID:          option.(map[string]interface{})["id"].(string),
-				Description: option.(map[string]interface{})["description"].(string),
-				Name:        option.(map[string]interface{})["name"].(string),
-				Archived:    option.(map[string]interface{})["archived"].(bool),
-				Released:    option.(map[string]interface{})["released"].(bool),
-				ReleaseDate: option.(map[string]interface{})["releaseDate"].(string),
-			}
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
 
-			records = append(records, record)
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		var customFields []*VersionDetailScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return records, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseUserPickerCustomField parses a user custom field from the given buffer data
+// associated with the specified custom field ID and pointer of the UserDetailScheme struct
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - *UserDetailScheme: A pointer of the UserDetailScheme struct
+//     representing the parsed group picker associated with the custom field.
+//
+// The UserDetailScheme is responsible for extracting and parsing the
+// serialized data from the provided buffer, which is expected to be in a specific format.
+// It then constructs and returns a slice of pointers to UserDetailScheme
+// structs that represent the parsed groups for the given custom field.
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	user, err := ParseUserPickerCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Printf("User ID: %s, User Name: %s\n", version.AccountID, version. DisplayName)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-userpicker-customfield
 func ParseUserPickerCustomField(buffer bytes.Buffer, customField string) (*UserDetailScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var user *UserDetailScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoUserTypeError
+	}
 
-	switch option := customFields[customField].(type) {
-	case map[string]interface{}:
+	var user UserDetailScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &user); err != nil {
+		return nil, ErrNoMultiSelectTypeError
+	}
+
+	return &user, nil
+}
+
+// ParseUserPickerCustomFields extracts and parses a user custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a UserDetailScheme struct pointer
+// ,representing the parsed cascading custom field value.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseUserPickerCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, data := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", data)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]*UserDetailScheme: A map where the key is the issue key and the
+//     value is a UserDetailScheme struct pointer representing the parsed
+//     cascading custom field value.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-userpicker-customfields
+func ParseUserPickerCustomFields(buffer bytes.Buffer, customField string) (map[string]*UserDetailScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-		user = &UserDetailScheme{
-			Self:        option["self"].(string),
-			AccountID:   option["accountId"].(string),
-			DisplayName: option["displayName"].(string),
-			Active:      option["active"].(bool),
-			TimeZone:    option["timeZone"].(string),
-			AccountType: option["accountType"].(string),
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]*UserDetailScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
 
-		email, wasFound := option["emailAddress"].(string)
-		if wasFound {
-			user.EmailAddress = email
+		var customFields *UserDetailScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return user, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseStringCustomField parses a textfield custom field from the given buffer data
+// associated with the specified custom field ID and returns string
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - string: the customfield value as string type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	textField, err := ParseStringCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(textField)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-textfield-customfield
 func ParseStringCustomField(buffer bytes.Buffer, customField string) (string, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return "", ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return "", ErrNoFieldInformationError
 	}
 
-	var text string
-	customFields := fields.(map[string]interface{})
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return "", ErrNoTextTypeError
+	}
+
+	return raw.Get(path).String(), nil
+}
+
+// ParseStringCustomFields extracts and parses the textfield customfield information from multiple issues using a bytes.Buffer.
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a string representing the parsed textfield customfield value.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseStringCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, data := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", data)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]string: A map where the key is the issue key and the
+//     value is a string with the customfield textfield value
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-textfield-customfields
+func ParseStringCustomFields(buffer bytes.Buffer, customField string) (map[string]string, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
+
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]string)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
 
-	switch value := customFields[customField].(type) {
-	case string:
-		text = value
-	case nil:
-		return "", nil
-	default:
-		return "", ErrNoMultiSelectTypeError
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
+
+		// Check if the customfield value is a string type
+		// if not, don't append the value on the map
+		if reflect.TypeOf(value.Get(path).Value()).Kind() == reflect.String {
+			customfieldsAsMap[issueKey] = value.Get(path).String()
+		}
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return text, err
+	return customfieldsAsMap, nil
 }
 
+// ParseFloatCustomField parses a float custom field from the given buffer data
+// associated with the specified custom field ID and returns float64 value
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - float64: the customfield value as float64 type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	floatField, err := ParseFloatCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(floatField)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-float-customfield
 func ParseFloatCustomField(buffer bytes.Buffer, customField string) (float64, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return 0, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return 0, ErrNoFieldInformationError
 	}
-	var number float64
-	customFields := fields.(map[string]interface{})
 
-	switch value := customFields[customField].(type) {
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return 0, ErrNoFloatTypeError
+	}
 
-	case float64:
-		number = value
-	case nil:
-		return 0, nil
-	default:
-		return 0, ErrNoMultiSelectTypeError
+	var textFloat float64
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &textFloat); err != nil {
+		return 0, ErrNoFloatTypeError
 	}
 
-	return number, err
+	return textFloat, nil
 }
 
-func ParseLabelCustomField(buffer bytes.Buffer, customField string) ([]string, error) {
+// ParseFloatCustomFields extracts and parses the float customfield information from multiple issues using a bytes.Buffer.
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a float64 representing the parsed float customfield value.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseFloatCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, data := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", data)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]float: A map where the key is the issue key and the
+//     value is a float64 value.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-float-customfields
+func ParseFloatCustomFields(buffer bytes.Buffer, customField string) (map[string]float64, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]float64)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
+
+		var customFields float64
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	return customfieldsAsMap, nil
+}
+
+// ParseLabelCustomField parses a textfield slice custom field from the given buffer data
+// associated with the specified custom field ID and returns string slice
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - []string: the customfield value as string slice type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	labels, err := ParseLabelCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(labels)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-labels-customfield
+func ParseLabelCustomField(buffer bytes.Buffer, customField string) ([]string, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
+
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoLabelsTypeError
+	}
+
 	var labels []string
-	switch value := customFields[customField].(type) {
-	case []interface{}:
-		for _, label := range value {
-			labels = append(labels, label.(string))
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &labels); err != nil {
+		return nil, ErrNoLabelsTypeError
+	}
+
+	return labels, nil
+}
+
+// ParseLabelCustomFields extracts and parses the textfield customfield information from multiple issues using a bytes.Buffer.
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a string slice representing the parsed labels customfield value.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseLabelCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, data := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", data)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string][]string: A map where the key is the issue key and the
+//     value is a string slice with the labels.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-labels-customfields
+func ParseLabelCustomFields(buffer bytes.Buffer, customField string) (map[string][]string, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
+
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]string)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+
+		var customFields []string
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return labels, err
+	return customfieldsAsMap, nil
 }
 
+// ParseSprintCustomField parses a sprints custom field from the given buffer data
+// associated with the specified custom field ID and returns the issue sprints
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - string: the customfield value as string type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	sprints, err := ParseSprintCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(sprints)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-sprints-customfield
 func ParseSprintCustomField(buffer bytes.Buffer, customField string) ([]*SprintDetailScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var records []*SprintDetailScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoSprintTypeError
+	}
 
-	switch options := customFields[customField].(type) {
-	case []interface{}:
+	var sprints []*SprintDetailScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &sprints); err != nil {
+		return nil, ErrNoSprintTypeError
+	}
+
+	return sprints, nil
+}
 
-		for _, option := range options {
+// ParseSprintCustomFields extracts and parses sprint custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a slice of SprintDetailScheme
+// structs, representing the parsed sprint custom field values.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseSprintCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, value := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", value)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the sprint custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string][]*SprintDetailScheme: A map where the key is the issue key and the
+//     value is a slice of SprintDetailScheme structs representing the parsed
+//     multi-select custom field values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-sprints-customfields
+func ParseSprintCustomFields(buffer bytes.Buffer, customField string) (map[string][]*SprintDetailScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-			record := &SprintDetailScheme{
-				Name:          option.(map[string]interface{})["name"].(string),
-				State:         option.(map[string]interface{})["state"].(string),
-				ID:            int(option.(map[string]interface{})["id"].(float64)),
-				StartDate:     option.(map[string]interface{})["startDate"].(string),
-				EndDate:       option.(map[string]interface{})["endDate"].(string),
-				OriginBoardID: int(option.(map[string]interface{})["boardId"].(float64)),
-				Goal:          option.(map[string]interface{})["goal"].(string),
-			}
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]*SprintDetailScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
 
-			completeDate, wasFound := option.(map[string]interface{})["completeDate"].(string)
-			if wasFound {
-				record.CompleteDate = completeDate
-			}
-			records = append(records, record)
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		var customFields []*SprintDetailScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return records, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseSelectCustomField parses a select custom field from the given buffer data
+// associated with the specified custom field ID and returns a CustomFieldContextOptionScheme struct
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - CustomFieldContextOptionScheme: the customfield value as CustomFieldContextOptionScheme type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	option, err := ParseSelectCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(option.ID, option.Value)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-select-customfield
 func ParseSelectCustomField(buffer bytes.Buffer, customField string) (*CustomFieldContextOptionScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
-	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
-	}
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
 		return nil, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var cascading *CustomFieldContextOptionScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoSelectTypeError
+	}
+
+	var sprints *CustomFieldContextOptionScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &sprints); err != nil {
+		return nil, ErrNoSelectTypeError
+	}
+
+	return sprints, nil
+}
 
-	switch option := customFields[customField].(type) {
-	case map[string]interface{}:
+// ParseSelectCustomFields extracts and parses select custom field data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a CustomFieldContextOptionScheme
+// struct, representing the parsed select custom field value.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseSelectCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, value := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", value)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]*CustomFieldContextOptionScheme: A map where the key is the issue key and the
+//     value is a CustomFieldContextOptionScheme struct representing the parsed
+//     multi-select custom field values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-select-customfields
+func ParseSelectCustomFields(buffer bytes.Buffer, customField string) (map[string]*CustomFieldContextOptionScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-		cascading = &CustomFieldContextOptionScheme{
-			ID:    option["id"].(string),
-			Value: option["value"].(string),
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]*CustomFieldContextOptionScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoMultiSelectTypeError
+		var customFields *CustomFieldContextOptionScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return cascading, nil
+	return customfieldsAsMap, nil
 }
 
+// ParseAssetCustomField parses the Jira assets elements from the given buffer data
+// associated with the specified custom field ID and returns a struct CustomFieldAssetScheme slice
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - []*CustomFieldAssetScheme: the customfield value as CustomFieldAssetScheme slice type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	assets, err := ParseAssetCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(assets)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-assets-customfield
 func ParseAssetCustomField(buffer bytes.Buffer, customField string) ([]*CustomFieldAssetScheme, error) {
 
-	raw, err := marshmallow.Unmarshal(buffer.Bytes(), &struct{}{})
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
+
+	// Check if the buffer contains the "fields" object
+	if !raw.Get("fields").Exists() {
+		return nil, ErrNoFieldInformationError
+	}
+
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return nil, ErrNoAssetTypeError
+	}
+
+	var assets []*CustomFieldAssetScheme
+	if err := json.Unmarshal([]byte(raw.Get(path).String()), &assets); err != nil {
+		return nil, ErrNoAssetTypeError
+	}
+
+	return assets, nil
+}
+
+// ParseAssetCustomFields extracts and parses jira assets customfield data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a slice of CustomFieldAssetScheme
+// structs, representing the parsed assets associated with a Jira issues.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseAssetCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, value := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", value)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]*CustomFieldAssetScheme: A map where the key is the issue key and the
+//     value is a CustomFieldAssetScheme struct representing the parsed
+//     jira assets values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-assets-customfields
+func ParseAssetCustomFields(buffer bytes.Buffer, customField string) (map[string][]*CustomFieldAssetScheme, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
+
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string][]*CustomFieldAssetScheme)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
+
+		var customFields []*CustomFieldAssetScheme
+		if err := json.Unmarshal([]byte(value.Get(path).String()), &customFields); err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = customFields
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
+	}
+
+	return customfieldsAsMap, nil
+}
+
+// ParseDatePickerCustomField parses the datepicker customfield from the given buffer data
+// associated with the specified custom field ID and returns a struct time.Time value
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - time.Time: the customfield value as time.Time type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	datepicker, err := ParseDatePickerCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(datepicker)
+//
+// https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-datepicker-customfield
+func ParseDatePickerCustomField(buffer bytes.Buffer, customField string) (time.Time, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("fields").Exists() {
+		return time.Time{}, ErrNoFieldInformationError
+	}
+
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return time.Time{}, ErrNoDatePickerTypeError
+	}
+
+	value, err := time.Parse("2006-01-02", raw.Get(path).String())
 	if err != nil {
-		return nil, ErrNoCustomFieldUnmarshalError
+		return time.Time{}, ErrNoDatePickerTypeError
 	}
 
-	fields, containsFields := raw["fields"]
-	if !containsFields {
-		return nil, ErrNoFieldInformationError
+	return value, nil
+}
+
+// ParseDatePickerCustomFields extracts and parses the datepicker customfield data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a time.Time value,
+// representing the parsed datepicker values with the Jira issues.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseDatePickerCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, value := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", value)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]time.Time: A map where the key is the issue key and the
+//     value is a time.Time representing the parsed jira datepicker values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-datepicker-customfields
+func ParseDatePickerCustomFields(buffer bytes.Buffer, customField string) (map[string]time.Time, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
+
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]time.Time)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
+		}
+
+		datepicker, err := time.Parse("2006-01-02", value.Get(path).String())
+		if err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = datepicker
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
+	}
+
+	return customfieldsAsMap, nil
+}
+
+// ParseDateTimeCustomField parses the datetime customfield from the given buffer data
+// associated with the specified custom field ID and returns a struct time.Time value
+//
+// Parameters:
+//   - customfieldID: A string representing the unique identifier of the custom field.
+//   - buffer: A bytes.Buffer containing the serialized data to be parsed.
+//
+// Returns:
+//   - time.Time: the customfield value as time.Time type
+//
+// Example usage:
+//
+//	customfieldID := "customfield_10001"
+//	buffer := bytes.NewBuffer([]byte{ /* Serialized data */ })
+//	datetime, err := ParseDateTimeCustomField(customfieldID, buffer)
+//	if err != nil {
+//	    log.Fatal(err)
+//	}
+//
+// fmt.Println(datetime)
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-datetime-customfield
+func ParseDateTimeCustomField(buffer bytes.Buffer, customField string) (time.Time, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+	path := fmt.Sprintf("fields.%v", customField)
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("fields").Exists() {
+		return time.Time{}, ErrNoFieldInformationError
 	}
 
-	customFields := fields.(map[string]interface{})
-	var records []*CustomFieldAssetScheme
+	// Check if the issue iteration contains information on the customfield selected,
+	// if not, continue
+	if raw.Get(path).Type == gjson.Null {
+		return time.Time{}, ErrNoDateTimeTypeError
+	}
 
-	switch options := customFields[customField].(type) {
-	case []interface{}:
+	value, err := time.Parse("2006-01-02T15:04:05.000-0700", raw.Get(path).String())
+	if err != nil {
+		return time.Time{}, ErrNoDateTimeTypeError
+	}
 
-		for _, option := range options {
+	return value, nil
+}
 
-			record := &CustomFieldAssetScheme{
-				WorkspaceId: option.(map[string]interface{})["workspaceId"].(string),
-				Id:          option.(map[string]interface{})["id"].(string),
-				ObjectId:    option.(map[string]interface{})["objectId"].(string),
-			}
+// ParseDateTimeCustomFields extracts and parses the datetime customfield data from a given bytes.Buffer from multiple issues
+//
+// This function takes the name of the custom field to parse and a bytes.Buffer containing
+// JSON data representing the custom field values associated with different issues. It returns
+// a map where the key is the issue key and the value is a time.Time value,
+// representing the parsed datetime values with the Jira issues.
+//
+// The JSON data within the buffer is expected to have a specific structure where the custom field
+// values are organized by issue keys and options are represented within a context. The function
+// parses this structure to extract and organize the custom field values.
+//
+// If the custom field data cannot be parsed successfully, an error is returned.
+//
+// Example Usage:
+//
+//	customFieldName := "customfield_10001"
+//	buffer := // Populate the buffer with JSON data
+//	customFields, err := ParseDateTimeCustomFields(customFieldName, buffer)
+//	if err != nil {
+//	    // Handle the error
+//	}
+//
+//	// Iterate through the parsed custom fields
+//	for issueKey, customFieldValues := range customFields {
+//	    fmt.Printf("Issue Key: %s\n", issueKey)
+//	    for _, value := range customFieldValues {
+//	        fmt.Printf("Custom Field Value: %+v\n", value)
+//	    }
+//	}
+//
+// Parameters:
+//   - customField: The name of the multi-select custom field to parse.
+//   - buffer: A bytes.Buffer containing JSON data representing custom field values.
+//
+// Returns:
+//   - map[string]time.Time: A map where the key is the issue key and the
+//     value is a time.Time representing the parsed jira datetime values.
+//   - error: An error if there was a problem parsing the custom field data or if the JSON data
+//     did not conform to the expected structure.
+//
+// Docs: https://docs.go-atlassian.io/cookbooks/extract-customfields-from-issue-s#parse-datetime-customfields
+func ParseDateTimeCustomFields(buffer bytes.Buffer, customField string) (map[string]time.Time, error) {
+
+	raw := gjson.ParseBytes(buffer.Bytes())
+
+	// Check if the buffer contains the "issues" object
+	if !raw.Get("issues").Exists() {
+		return nil, ErrNoIssuesSliceError
+	}
 
-			records = append(records, record)
+	// Loop through each custom field, extract the information and stores the data on a map
+	customfieldsAsMap := make(map[string]time.Time)
+	raw.Get("issues").ForEach(func(key, value gjson.Result) bool {
+
+		path, issueKey := fmt.Sprintf("fields.%v", customField), value.Get("key").String()
+
+		// Check if the issue iteration contains information on the customfield selected,
+		// if not, continue
+		if value.Get(path).Type == gjson.Null {
+			return true
 		}
 
-	case nil:
-		return nil, nil
-	default:
-		return nil, ErrNoAssetTypeError
+		datepicker, err := time.Parse("2006-01-02T15:04:05.000-0700", value.Get(path).String())
+		if err != nil {
+			return true
+		}
+
+		customfieldsAsMap[issueKey] = datepicker
+		return true
+	})
+
+	// Check if the map processed contains elements
+	// if so, return an error interface
+	if len(customfieldsAsMap) == 0 {
+		return nil, ErrNoMapValuesError
 	}
 
-	return records, nil
+	return customfieldsAsMap, nil
 }
diff --git a/pkg/infra/models/sm_request_field.go b/pkg/infra/models/sm_request_field.go
index d32ec8a..e867894 100644
--- a/pkg/infra/models/sm_request_field.go
+++ b/pkg/infra/models/sm_request_field.go
@@ -36,7 +36,7 @@ func (c *CreateCustomerRequestPayloadScheme) DateTimeCustomField(id string, valu
 	}
 
 	if value.IsZero() {
-		return ErrNoDateTimeTypeError
+		return ErrNoDatePickerTypeError
 	}
 
 	return c.AddCustomField(id, value.Format(time.RFC3339))
@@ -49,7 +49,7 @@ func (c *CreateCustomerRequestPayloadScheme) DateCustomField(id string, value ti
 	}
 
 	if value.IsZero() {
-		return ErrNoDateTimeTypeError
+		return ErrNoDatePickerTypeError
 	}
 
 	return c.AddCustomField(id, value.Format("2006-01-02"))


Test patch:
diff --git a/pkg/infra/models/jira_customFields_test.go b/pkg/infra/models/jira_customFields_test.go
index 06a78f0..3d9f40d 100644
--- a/pkg/infra/models/jira_customFields_test.go
+++ b/pkg/infra/models/jira_customFields_test.go
@@ -204,7 +204,7 @@ func TestCustomFields_Date(t *testing.T) {
 				dateTimeValue: time.Time{},
 			},
 			wantErr: true,
-			Err:     ErrNoDateTypeError,
+			Err:     ErrNoDateTimeTypeError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -275,7 +275,7 @@ func TestCustomFields_DateTime(t *testing.T) {
 				dateValue:     time.Time{},
 			},
 			wantErr: true,
-			Err:     ErrNoDateTimeTypeError,
+			Err:     ErrNoDatePickerTypeError,
 		},
 	}
 	for _, testCase := range testCases {
diff --git a/pkg/infra/models/jira_issue_custom_fields_test.go b/pkg/infra/models/jira_issue_custom_fields_test.go
index e1cb36f..75d1a2c 100644
--- a/pkg/infra/models/jira_issue_custom_fields_test.go
+++ b/pkg/infra/models/jira_issue_custom_fields_test.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"reflect"
 	"testing"
+	"time"
 )
 
 func TestParseMultiSelectField(t *testing.T) {
@@ -60,7 +61,7 @@ func TestParseMultiSelectField(t *testing.T) {
 	bufferMockedWithNoInfo.WriteString(`
 {
 	"fields": {
-		"customfield_10046": null
+		"w": null
 	}
 }`)
 
@@ -107,7 +108,6 @@ func TestParseMultiSelectField(t *testing.T) {
 					Value: "Option 4",
 				},
 			},
-			want1:   true,
 			wantErr: false,
 		},
 
@@ -118,8 +118,8 @@ func TestParseMultiSelectField(t *testing.T) {
 				customField: "customfield_10046",
 			},
 			want:    nil,
-			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoMultiSelectTypeError,
 		},
 
 		{
@@ -129,7 +129,6 @@ func TestParseMultiSelectField(t *testing.T) {
 				customField: "customfield_10046",
 			},
 			want:    nil,
-			want1:   false,
 			wantErr: true,
 			Err:     ErrNoFieldInformationError,
 		},
@@ -141,7 +140,6 @@ func TestParseMultiSelectField(t *testing.T) {
 				customField: "customfield_10046",
 			},
 			want:    nil,
-			want1:   false,
 			wantErr: true,
 			Err:     ErrNoMultiSelectTypeError,
 		},
@@ -153,9 +151,8 @@ func TestParseMultiSelectField(t *testing.T) {
 				customField: "customfield_10046",
 			},
 			want:    nil,
-			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -220,19 +217,19 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 
 	bufferMockedWithNoInfo := bytes.Buffer{}
 	bufferMockedWithNoInfo.WriteString(`
-{
-	"fields": {
-		"customfield_10052": null
-	}
-}`)
+	{
+		"fields": {
+			"customfield_10052": null
+		}
+	}`)
 
 	bufferMockedWithInvalidType := bytes.Buffer{}
 	bufferMockedWithInvalidType.WriteString(`
-{
-	"fields": {
-		"customfield_10052": "Test field sample"
-	}
-}`)
+	{
+		"fields": {
+			"customfield_10052": "Test field sample"
+		}
+	}`)
 
 	type args struct {
 		buffer      bytes.Buffer
@@ -243,7 +240,6 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 		name    string
 		args    args
 		want    []*GroupDetailScheme
-		want1   bool
 		wantErr bool
 		Err     error
 	}{
@@ -265,7 +261,6 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 					GroupID: "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
 				},
 			},
-			want1:   true,
 			wantErr: false,
 		},
 
@@ -276,8 +271,8 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 				customField: "customfield_10052",
 			},
 			want:    nil,
-			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoMultiSelectTypeError,
 		},
 
 		{
@@ -287,7 +282,6 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 				customField: "customfield_10052",
 			},
 			want:    nil,
-			want1:   false,
 			wantErr: true,
 			Err:     ErrNoFieldInformationError,
 		},
@@ -299,7 +293,6 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 				customField: "customfield_10052",
 			},
 			want:    nil,
-			want1:   false,
 			wantErr: true,
 			Err:     ErrNoMultiSelectTypeError,
 		},
@@ -311,9 +304,8 @@ func TestParseMultiGroupPickerField(t *testing.T) {
 				customField: "customfield_10052",
 			},
 			want:    nil,
-			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -502,8 +494,8 @@ func TestParseMultiUserPickerField(t *testing.T) {
 				customField: "customfield_10055",
 			},
 			want:    nil,
-			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoMultiSelectTypeError,
 		},
 
 		{
@@ -539,7 +531,7 @@ func TestParseMultiUserPickerField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -655,7 +647,8 @@ func TestParseCascadingSelectField(t *testing.T) {
 			},
 			want:    nil,
 			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoCascadingParentError,
 		},
 
 		{
@@ -679,7 +672,7 @@ func TestParseCascadingSelectField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
+			Err:     ErrNoCascadingParentError,
 		},
 
 		{
@@ -691,7 +684,7 @@ func TestParseCascadingSelectField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -712,162 +705,6 @@ func TestParseCascadingSelectField(t *testing.T) {
 	}
 }
 
-func TestParseMultiCheckboxesCustomField(t *testing.T) {
-
-	bufferMocked := bytes.Buffer{}
-	bufferMocked.WriteString(`
-{
-	"fields": {
-		"customfield_10046": [
-      {
-        "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10037",
-        "value": "Option 2",
-        "id": "10037"
-      },
-      {
-        "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10039",
-        "value": "Options 4",
-        "id": "10039"
-      }
-    ]
-	}
-}`)
-
-	bufferMockedWithNoFields := bytes.Buffer{}
-	bufferMockedWithNoFields.WriteString(`
-{
-	"field_no_mapped": {
-		"customfield_10046": [
-      {
-        "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10037",
-        "value": "Option 2",
-        "id": "10037"
-      },
-      {
-        "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10039",
-        "value": "Options 4",
-        "id": "10039"
-      }
-    ]
-	}
-}`)
-
-	bufferMockedWithNoJSON := bytes.Buffer{}
-	bufferMockedWithNoJSON.WriteString(`{}{`)
-
-	bufferMockedWithNoInfo := bytes.Buffer{}
-	bufferMockedWithNoInfo.WriteString(`
-{
-	"fields": {
-		"customfield_10046": null
-	}
-}`)
-
-	bufferMockedWithInvalidType := bytes.Buffer{}
-	bufferMockedWithInvalidType.WriteString(`
-{
-	"fields": {
-		"customfield_10046": "Test field sample"
-	}
-}`)
-
-	type args struct {
-		buffer      bytes.Buffer
-		customField string
-	}
-
-	testCases := []struct {
-		name    string
-		args    args
-		want    []*CustomFieldContextOptionScheme
-		want1   bool
-		wantErr bool
-		Err     error
-	}{
-		{
-			name: "when the buffer contains information",
-			args: args{
-				buffer:      bufferMocked,
-				customField: "customfield_10046",
-			},
-			want: []*CustomFieldContextOptionScheme{
-				{
-					ID:    "10037",
-					Value: "Option 2",
-				},
-				{
-					ID:    "10039",
-					Value: "Options 4",
-				},
-			},
-			want1:   true,
-			wantErr: false,
-		},
-
-		{
-			name: "when the buffer no contains information",
-			args: args{
-				buffer:      bufferMockedWithNoInfo,
-				customField: "customfield_10046",
-			},
-			want:    nil,
-			want1:   false,
-			wantErr: false,
-		},
-
-		{
-			name: "when the buffer does not contains the fields object",
-			args: args{
-				buffer:      bufferMockedWithNoFields,
-				customField: "customfield_10046",
-			},
-			want:    nil,
-			want1:   false,
-			wantErr: true,
-			Err:     ErrNoFieldInformationError,
-		},
-
-		{
-			name: "when the buffer does not contains a valid field type",
-			args: args{
-				buffer:      bufferMockedWithInvalidType,
-				customField: "customfield_10046",
-			},
-			want:    nil,
-			want1:   false,
-			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
-		},
-
-		{
-			name: "when the buffer cannot be parsed",
-			args: args{
-				buffer:      bufferMockedWithNoJSON,
-				customField: "customfield_10046",
-			},
-			want:    nil,
-			want1:   false,
-			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
-		},
-	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			got, err := ParseMultiCheckboxesCustomField(testCase.args.buffer, testCase.args.customField)
-			if (err != nil) != testCase.wantErr {
-				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, testCase.want) {
-				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
-			}
-			if !reflect.DeepEqual(err, testCase.Err) {
-				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
-			}
-		})
-	}
-}
-
 func TestParseMultiVersionCustomField(t *testing.T) {
 
 	bufferMocked := bytes.Buffer{}
@@ -994,7 +831,8 @@ func TestParseMultiVersionCustomField(t *testing.T) {
 			},
 			want:    nil,
 			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoMultiVersionTypeError,
 		},
 
 		{
@@ -1030,7 +868,7 @@ func TestParseMultiVersionCustomField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -1155,7 +993,8 @@ func TestParseUserPickerCustomField(t *testing.T) {
 			},
 			want:    nil,
 			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoUserTypeError,
 		},
 
 		{
@@ -1191,7 +1030,7 @@ func TestParseUserPickerCustomField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -1218,7 +1057,7 @@ func TestParseStringCustomField(t *testing.T) {
 	bufferMocked.WriteString(`
 {
   "fields": {
-    "customfield_10045": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
+    "customfield_10045": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr"
   }
 }`)
 
@@ -1267,17 +1106,7 @@ func TestParseStringCustomField(t *testing.T) {
 				buffer:      bufferMocked,
 				customField: "customfield_10045",
 			},
-			want:    "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
-			wantErr: false,
-		},
-
-		{
-			name: "when the buffer no contains information",
-			args: args{
-				buffer:      bufferMockedWithNoInfo,
-				customField: "customfield_10045",
-			},
-			want:    "",
+			want:    "Lorem ipsum dolor sit amet, consetetur sadipscing elitr",
 			wantErr: false,
 		},
 
@@ -1293,25 +1122,25 @@ func TestParseStringCustomField(t *testing.T) {
 		},
 
 		{
-			name: "when the buffer does not contains a valid field type",
+			name: "when the buffer field value is null",
 			args: args{
-				buffer:      bufferMockedWithInvalidType,
+				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10045",
 			},
 			want:    "",
 			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
+			Err:     ErrNoTextTypeError,
 		},
 
 		{
 			name: "when the buffer cannot be parsed",
 			args: args{
-				buffer:      bufferMockedWithNoJSON,
+				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10045",
 			},
 			want:    "",
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoTextTypeError,
 		},
 	}
 	for _, testCase := range testCases {
@@ -1332,13 +1161,13 @@ func TestParseStringCustomField(t *testing.T) {
 	}
 }
 
-func TestParseFloatCustomField(t *testing.T) {
+func TestParseDatePickerCustomField(t *testing.T) {
 
 	bufferMocked := bytes.Buffer{}
 	bufferMocked.WriteString(`
 {
   "fields": {
-    "customfield_10045": 1000.323
+    "customfield_10045": "2023-09-22"
   }
 }`)
 
@@ -1346,7 +1175,7 @@ func TestParseFloatCustomField(t *testing.T) {
 	bufferMockedWithNoFields.WriteString(`
 {
   "fields_no_mapped": {
-    "customfield_10045": 1000.323
+    "customfield_10045": "2023-09-22"
   }
 }`)
 
@@ -1365,7 +1194,7 @@ func TestParseFloatCustomField(t *testing.T) {
 	bufferMockedWithInvalidType.WriteString(`
 {
 	"fields": {
-		"customfield_10045": "Test field sample"
+		"customfield_10045": 10023.345
 	}
 }`)
 
@@ -1377,7 +1206,7 @@ func TestParseFloatCustomField(t *testing.T) {
 	testCases := []struct {
 		name    string
 		args    args
-		want    float64
+		want    time.Time
 		wantErr bool
 		Err     error
 	}{
@@ -1387,17 +1216,7 @@ func TestParseFloatCustomField(t *testing.T) {
 				buffer:      bufferMocked,
 				customField: "customfield_10045",
 			},
-			want:    1000.323,
-			wantErr: false,
-		},
-
-		{
-			name: "when the buffer no contains information",
-			args: args{
-				buffer:      bufferMockedWithNoInfo,
-				customField: "customfield_10045",
-			},
-			want:    0,
+			want:    time.Date(2023, time.September, 22, 0, 0, 0, 0, time.UTC),
 			wantErr: false,
 		},
 
@@ -1407,36 +1226,33 @@ func TestParseFloatCustomField(t *testing.T) {
 				buffer:      bufferMockedWithNoFields,
 				customField: "customfield_10045",
 			},
-			want:    0,
 			wantErr: true,
 			Err:     ErrNoFieldInformationError,
 		},
 
 		{
-			name: "when the buffer does not contains a valid field type",
+			name: "when the buffer field value is null",
 			args: args{
-				buffer:      bufferMockedWithInvalidType,
+				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10045",
 			},
-			want:    0,
 			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
+			Err:     ErrNoDatePickerTypeError,
 		},
 
 		{
 			name: "when the buffer cannot be parsed",
 			args: args{
-				buffer:      bufferMockedWithNoJSON,
+				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10045",
 			},
-			want:    0,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoDatePickerTypeError,
 		},
 	}
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			got, err := ParseFloatCustomField(testCase.args.buffer, testCase.args.customField)
+			got, err := ParseDatePickerCustomField(testCase.args.buffer, testCase.args.customField)
 			if (err != nil) != testCase.wantErr {
 				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
 				return
@@ -1452,16 +1268,18 @@ func TestParseFloatCustomField(t *testing.T) {
 	}
 }
 
-func TestParseLabelCustomField(t *testing.T) {
+func TestParseDateTimeCustomField(t *testing.T) {
+
+	mockedTime, err := time.Parse("2006-01-02T15:04:05.000-0700", "2023-07-12T16:00:00.000+0100")
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	bufferMocked := bytes.Buffer{}
 	bufferMocked.WriteString(`
 {
   "fields": {
-    "customfield_10045": [
-      "asd",
-      "asds"
-    ]
+    "customfield_10045": "2023-07-12T16:00:00.000+0100"
   }
 }`)
 
@@ -1469,10 +1287,7 @@ func TestParseLabelCustomField(t *testing.T) {
 	bufferMockedWithNoFields.WriteString(`
 {
   "fields_no_mapped": {
-   "customfield_10045": [
-      "asd",
-      "asds"
-    ]
+    "customfield_10045": "2023-07-12T16:00:00.000+0100"
   }
 }`)
 
@@ -1491,7 +1306,7 @@ func TestParseLabelCustomField(t *testing.T) {
 	bufferMockedWithInvalidType.WriteString(`
 {
 	"fields": {
-		"customfield_10045": "Test field sample"
+		"customfield_10045": 10023.345
 	}
 }`)
 
@@ -1503,7 +1318,7 @@ func TestParseLabelCustomField(t *testing.T) {
 	testCases := []struct {
 		name    string
 		args    args
-		want    []string
+		want    time.Time
 		wantErr bool
 		Err     error
 	}{
@@ -1513,17 +1328,7 @@ func TestParseLabelCustomField(t *testing.T) {
 				buffer:      bufferMocked,
 				customField: "customfield_10045",
 			},
-			want:    []string{"asd", "asds"},
-			wantErr: false,
-		},
-
-		{
-			name: "when the buffer no contains information",
-			args: args{
-				buffer:      bufferMockedWithNoInfo,
-				customField: "customfield_10045",
-			},
-			want:    nil,
+			want:    mockedTime,
 			wantErr: false,
 		},
 
@@ -1533,36 +1338,33 @@ func TestParseLabelCustomField(t *testing.T) {
 				buffer:      bufferMockedWithNoFields,
 				customField: "customfield_10045",
 			},
-			want:    nil,
 			wantErr: true,
 			Err:     ErrNoFieldInformationError,
 		},
 
 		{
-			name: "when the buffer does not contains a valid field type",
+			name: "when the buffer field value is null",
 			args: args{
-				buffer:      bufferMockedWithInvalidType,
+				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10045",
 			},
-			want:    nil,
 			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
+			Err:     ErrNoDateTimeTypeError,
 		},
 
 		{
 			name: "when the buffer cannot be parsed",
 			args: args{
-				buffer:      bufferMockedWithNoJSON,
+				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10045",
 			},
-			want:    nil,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoDateTimeTypeError,
 		},
 	}
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			got, err := ParseLabelCustomField(testCase.args.buffer, testCase.args.customField)
+			got, err := ParseDateTimeCustomField(testCase.args.buffer, testCase.args.customField)
 			if (err != nil) != testCase.wantErr {
 				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
 				return
@@ -1578,43 +1380,22 @@ func TestParseLabelCustomField(t *testing.T) {
 	}
 }
 
-func TestParseSprintCustomField(t *testing.T) {
+func TestParseFloatCustomField(t *testing.T) {
 
 	bufferMocked := bytes.Buffer{}
 	bufferMocked.WriteString(`
 {
-	"fields": {
-		"customfield_10046": [
-      {
-        "id": 4,
-        "name": "KP Sprint 3",
-        "state": "active",
-        "boardId": 4,
-        "goal": "",
-        "startDate": "2023-03-04T02:03:16.273Z",
-        "endDate": "2023-03-17T02:03:00.000Z",
-		"completeDate": "2023-03-04T02:03:16.273Z"
-      }
-    ]
-	}
+  "fields": {
+    "customfield_10045": 1000.323
+  }
 }`)
 
 	bufferMockedWithNoFields := bytes.Buffer{}
 	bufferMockedWithNoFields.WriteString(`
 {
-	"field_no_mapped": {
-		"customfield_10046": [
-      {
-        "id": 4,
-        "name": "KP Sprint 3",
-        "state": "active",
-        "boardId": 4,
-        "goal": "",
-        "startDate": "2023-03-04T02:03:16.273Z",
-        "endDate": "2023-03-17T02:03:00.000Z"
-      }
-    ]
-	}
+  "fields_no_mapped": {
+    "customfield_10045": 1000.323
+  }
 }`)
 
 	bufferMockedWithNoJSON := bytes.Buffer{}
@@ -1624,7 +1405,7 @@ func TestParseSprintCustomField(t *testing.T) {
 	bufferMockedWithNoInfo.WriteString(`
 {
 	"fields": {
-		"customfield_10046": null
+		"customfield_10045": null
 	}
 }`)
 
@@ -1632,7 +1413,7 @@ func TestParseSprintCustomField(t *testing.T) {
 	bufferMockedWithInvalidType.WriteString(`
 {
 	"fields": {
-		"customfield_10046": "Test field sample"
+		"customfield_10045": "Test field sample"
 	}
 }`)
 
@@ -1644,8 +1425,7 @@ func TestParseSprintCustomField(t *testing.T) {
 	testCases := []struct {
 		name    string
 		args    args
-		want    []*SprintDetailScheme
-		want1   bool
+		want    float64
 		wantErr bool
 		Err     error
 	}{
@@ -1653,21 +1433,9 @@ func TestParseSprintCustomField(t *testing.T) {
 			name: "when the buffer contains information",
 			args: args{
 				buffer:      bufferMocked,
-				customField: "customfield_10046",
-			},
-			want: []*SprintDetailScheme{
-				{
-					ID:            4,
-					State:         "active",
-					Name:          "KP Sprint 3",
-					StartDate:     "2023-03-04T02:03:16.273Z",
-					CompleteDate:  "2023-03-04T02:03:16.273Z",
-					EndDate:       "2023-03-17T02:03:00.000Z",
-					OriginBoardID: 4,
-					Goal:          "",
-				},
+				customField: "customfield_10045",
 			},
-			want1:   true,
+			want:    1000.323,
 			wantErr: false,
 		},
 
@@ -1675,21 +1443,20 @@ func TestParseSprintCustomField(t *testing.T) {
 			name: "when the buffer no contains information",
 			args: args{
 				buffer:      bufferMockedWithNoInfo,
-				customField: "customfield_10046",
+				customField: "customfield_10045",
 			},
-			want:    nil,
-			want1:   false,
-			wantErr: false,
+			want:    0,
+			wantErr: true,
+			Err:     ErrNoFloatTypeError,
 		},
 
 		{
 			name: "when the buffer does not contains the fields object",
 			args: args{
 				buffer:      bufferMockedWithNoFields,
-				customField: "customfield_10046",
+				customField: "customfield_10045",
 			},
-			want:    nil,
-			want1:   false,
+			want:    0,
 			wantErr: true,
 			Err:     ErrNoFieldInformationError,
 		},
@@ -1698,29 +1465,27 @@ func TestParseSprintCustomField(t *testing.T) {
 			name: "when the buffer does not contains a valid field type",
 			args: args{
 				buffer:      bufferMockedWithInvalidType,
-				customField: "customfield_10046",
+				customField: "customfield_10045",
 			},
-			want:    nil,
-			want1:   false,
+			want:    0,
 			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
+			Err:     ErrNoFloatTypeError,
 		},
 
 		{
 			name: "when the buffer cannot be parsed",
 			args: args{
 				buffer:      bufferMockedWithNoJSON,
-				customField: "customfield_10046",
+				customField: "customfield_10045",
 			},
-			want:    nil,
-			want1:   false,
+			want:    0,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			got, err := ParseSprintCustomField(testCase.args.buffer, testCase.args.customField)
+			got, err := ParseFloatCustomField(testCase.args.buffer, testCase.args.customField)
 			if (err != nil) != testCase.wantErr {
 				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
 				return
@@ -1728,6 +1493,7 @@ func TestParseSprintCustomField(t *testing.T) {
 			if !reflect.DeepEqual(got, testCase.want) {
 				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
 			}
+
 			if !reflect.DeepEqual(err, testCase.Err) {
 				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
 			}
@@ -1735,17 +1501,16 @@ func TestParseSprintCustomField(t *testing.T) {
 	}
 }
 
-func TestParseSelectCustomField(t *testing.T) {
+func TestParseLabelCustomField(t *testing.T) {
 
 	bufferMocked := bytes.Buffer{}
 	bufferMocked.WriteString(`
 {
   "fields": {
-    "customfield_10045": {
-      "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
-      "value": "Scranton 1",
-      "id": "10058"
-    }
+    "customfield_10045": [
+      "asd",
+      "asds"
+    ]
   }
 }`)
 
@@ -1753,11 +1518,10 @@ func TestParseSelectCustomField(t *testing.T) {
 	bufferMockedWithNoFields.WriteString(`
 {
   "fields_no_mapped": {
-   "customfield_10045": {
-      "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
-      "value": "Scranton 1",
-      "id": "10058"
-    }
+   "customfield_10045": [
+      "asd",
+      "asds"
+    ]
   }
 }`)
 
@@ -1788,7 +1552,7 @@ func TestParseSelectCustomField(t *testing.T) {
 	testCases := []struct {
 		name    string
 		args    args
-		want    *CustomFieldContextOptionScheme
+		want    []string
 		wantErr bool
 		Err     error
 	}{
@@ -1798,10 +1562,7 @@ func TestParseSelectCustomField(t *testing.T) {
 				buffer:      bufferMocked,
 				customField: "customfield_10045",
 			},
-			want: &CustomFieldContextOptionScheme{
-				ID:    "10058",
-				Value: "Scranton 1",
-			},
+			want:    []string{"asd", "asds"},
 			wantErr: false,
 		},
 
@@ -1812,7 +1573,8 @@ func TestParseSelectCustomField(t *testing.T) {
 				customField: "customfield_10045",
 			},
 			want:    nil,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoLabelsTypeError,
 		},
 
 		{
@@ -1834,7 +1596,7 @@ func TestParseSelectCustomField(t *testing.T) {
 			},
 			want:    nil,
 			wantErr: true,
-			Err:     ErrNoMultiSelectTypeError,
+			Err:     ErrNoLabelsTypeError,
 		},
 
 		{
@@ -1845,28 +1607,28 @@ func TestParseSelectCustomField(t *testing.T) {
 			},
 			want:    nil,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			got, err := ParseSelectCustomField(testCase.args.buffer, testCase.args.customField)
+			got, err := ParseLabelCustomField(testCase.args.buffer, testCase.args.customField)
 			if (err != nil) != testCase.wantErr {
-				t.Errorf("ParseSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
 				return
 			}
 			if !reflect.DeepEqual(got, testCase.want) {
-				t.Errorf("ParseSelectCustomField() got = %v, want %v", got, testCase.want)
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
 			}
 
 			if !reflect.DeepEqual(err, testCase.Err) {
-				t.Errorf("ParseSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
 			}
 		})
 	}
 }
 
-func TestParseAssetCustomField(t *testing.T) {
+func TestParseSprintCustomField(t *testing.T) {
 
 	bufferMocked := bytes.Buffer{}
 	bufferMocked.WriteString(`
@@ -1874,9 +1636,14 @@ func TestParseAssetCustomField(t *testing.T) {
 	"fields": {
 		"customfield_10046": [
       {
-        "workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
-        "id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
-        "objectId": "1"
+        "id": 5,
+        "name": "KP Sprint 3",
+        "state": "active",
+        "boardId": 4,
+        "goal": "",
+        "startDate": "2023-03-04T02:03:16.273Z",
+        "endDate": "2023-03-17T02:03:00.000Z",
+		"completeDate": "2023-03-04T02:03:16.273Z"
       }
     ]
 	}
@@ -1887,10 +1654,14 @@ func TestParseAssetCustomField(t *testing.T) {
 {
 	"field_no_mapped": {
 		"customfield_10046": [
-     {
-        "workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
-        "id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
-        "objectId": "1"
+      {
+        "id": 5,
+        "name": "KP Sprint 3",
+        "state": "active",
+        "boardId": 4,
+        "goal": "",
+        "startDate": "2023-03-04T02:03:16.273Z",
+        "endDate": "2023-03-17T02:03:00.000Z"
       }
     ]
 	}
@@ -1923,7 +1694,7 @@ func TestParseAssetCustomField(t *testing.T) {
 	testCases := []struct {
 		name    string
 		args    args
-		want    []*CustomFieldAssetScheme
+		want    []*SprintDetailScheme
 		want1   bool
 		wantErr bool
 		Err     error
@@ -1934,11 +1705,16 @@ func TestParseAssetCustomField(t *testing.T) {
 				buffer:      bufferMocked,
 				customField: "customfield_10046",
 			},
-			want: []*CustomFieldAssetScheme{
+			want: []*SprintDetailScheme{
 				{
-					WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f1",
-					Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
-					ObjectId:    "1",
+					ID:           5,
+					State:        "active",
+					Name:         "KP Sprint 3",
+					StartDate:    "2023-03-04T02:03:16.273Z",
+					CompleteDate: "2023-03-04T02:03:16.273Z",
+					EndDate:      "2023-03-17T02:03:00.000Z",
+					BoardID:      4,
+					Goal:         "",
 				},
 			},
 			want1:   true,
@@ -1951,9 +1727,8 @@ func TestParseAssetCustomField(t *testing.T) {
 				buffer:      bufferMockedWithNoInfo,
 				customField: "customfield_10046",
 			},
-			want:    nil,
-			want1:   false,
-			wantErr: false,
+			wantErr: true,
+			Err:     ErrNoSprintTypeError,
 		},
 
 		{
@@ -1977,7 +1752,7 @@ func TestParseAssetCustomField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoAssetTypeError,
+			Err:     ErrNoSprintTypeError,
 		},
 
 		{
@@ -1989,12 +1764,12 @@ func TestParseAssetCustomField(t *testing.T) {
 			want:    nil,
 			want1:   false,
 			wantErr: true,
-			Err:     ErrNoCustomFieldUnmarshalError,
+			Err:     ErrNoFieldInformationError,
 		},
 	}
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			got, err := ParseAssetCustomField(testCase.args.buffer, testCase.args.customField)
+			got, err := ParseSprintCustomField(testCase.args.buffer, testCase.args.customField)
 			if (err != nil) != testCase.wantErr {
 				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
 				return
@@ -2008,3 +1783,4291 @@ func TestParseAssetCustomField(t *testing.T) {
 		})
 	}
 }
+
+func TestParseSelectCustomField(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+  "fields": {
+    "customfield_10045": {
+      "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
+      "value": "Scranton 1",
+      "id": "10058"
+    }
+  }
+}`)
+
+	bufferMockedWithNoFields := bytes.Buffer{}
+	bufferMockedWithNoFields.WriteString(`
+{
+  "fields_no_mapped": {
+   "customfield_10045": {
+      "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
+      "value": "Scranton 1",
+      "id": "10058"
+    }
+  }
+}`)
+
+	bufferMockedWithNoJSON := bytes.Buffer{}
+	bufferMockedWithNoJSON.WriteString(`{}{`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+	"fields": {
+		"customfield_10045": null
+	}
+}`)
+
+	bufferMockedWithInvalidType := bytes.Buffer{}
+	bufferMockedWithInvalidType.WriteString(`
+{
+	"fields": {
+		"customfield_10045": "Test field sample"
+	}
+}`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+
+	testCases := []struct {
+		name    string
+		args    args
+		want    *CustomFieldContextOptionScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10045",
+			},
+			want: &CustomFieldContextOptionScheme{
+				ID:    "10058",
+				Value: "Scranton 1",
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer no contains information",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10045",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoSelectTypeError,
+		},
+
+		{
+			name: "when the buffer does not contains the fields object",
+			args: args{
+				buffer:      bufferMockedWithNoFields,
+				customField: "customfield_10045",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoFieldInformationError,
+		},
+
+		{
+			name: "when the buffer does not contains a valid field type",
+			args: args{
+				buffer:      bufferMockedWithInvalidType,
+				customField: "customfield_10045",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoSelectTypeError,
+		},
+
+		{
+			name: "when the buffer cannot be parsed",
+			args: args{
+				buffer:      bufferMockedWithNoJSON,
+				customField: "customfield_10045",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoFieldInformationError,
+		},
+	}
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseSelectCustomField(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseAssetCustomField(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+	"fields": {
+		"customfield_10046": [
+		 {
+			"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+			"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+			"objectId": "1"
+		  }
+		]
+	}
+}`)
+
+	bufferMockedWithNoFields := bytes.Buffer{}
+	bufferMockedWithNoFields.WriteString(`
+{
+	"field_no_mapped": {
+		"customfield_10046": [
+		 {
+			"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+			"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+			"objectId": "1"
+		  }
+		]
+	}
+}`)
+
+	bufferMockedWithNoJSON := bytes.Buffer{}
+	bufferMockedWithNoJSON.WriteString(`{}{`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+	"fields": {
+		"w": null
+	}
+}`)
+
+	bufferMockedWithInvalidType := bytes.Buffer{}
+	bufferMockedWithInvalidType.WriteString(`
+{
+	"fields": {
+		"customfield_10046": "Test field sample"
+	}
+}`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+
+	testCases := []struct {
+		name    string
+		args    args
+		want    []*CustomFieldAssetScheme
+		want1   bool
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: []*CustomFieldAssetScheme{
+				{
+					WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f1",
+					Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+					ObjectId:    "1",
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer no contains information",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoAssetTypeError,
+		},
+
+		{
+			name: "when the buffer does not contains the fields object",
+			args: args{
+				buffer:      bufferMockedWithNoFields,
+				customField: "customfield_10046",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoFieldInformationError,
+		},
+
+		{
+			name: "when the buffer does not contains a valid field type",
+			args: args{
+				buffer:      bufferMockedWithInvalidType,
+				customField: "customfield_10046",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoAssetTypeError,
+		},
+
+		{
+			name: "when the buffer cannot be parsed",
+			args: args{
+				buffer:      bufferMockedWithNoJSON,
+				customField: "customfield_10046",
+			},
+			want:    nil,
+			wantErr: true,
+			Err:     ErrNoFieldInformationError,
+		},
+	}
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseAssetCustomField(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseMultiSelectCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithInvalidType := bytes.Buffer{}
+	bufferMockedWithInvalidType.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": "string"
+            }
+        }
+    ]
+}`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]*CustomFieldContextOptionScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*CustomFieldContextOptionScheme{
+				"KP-22": {
+					{
+						ID:    "10046",
+						Value: "Option 3",
+					},
+					{
+						ID:    "10047",
+						Value: "Option 4",
+					},
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*CustomFieldContextOptionScheme{
+				"KP-22": {
+					{
+						ID:    "10046",
+						Value: "Option 3",
+					},
+					{
+						ID:    "10047",
+						Value: "Option 4",
+					},
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseMultiSelectCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseMultiGroupPickerCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": [
+				  {
+					"name": "jira-administrators",
+					"groupId": "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764"
+				  },
+				  {
+					"name": "jira-administrators-system",
+					"groupId": "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a"
+				  }
+				]
+            }
+        },
+		{
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-23",
+            "fields": {
+                "customfield_10046": [
+				  {
+					"name": "jira-administrators-2",
+					"groupId": "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764"
+				  },
+				  {
+					"name": "jira-administrators-system-2",
+					"groupId": "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a"
+				  }
+				]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null,
+            }
+        },
+		{
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-23",
+            "fields": {
+                "customfield_10046": [
+				  {
+					"name": "jira-administrators-2",
+					"groupId": "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764"
+				  },
+				  {
+					"name": "jira-administrators-system-2",
+					"groupId": "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a"
+				  }
+				]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            }
+        },
+		{
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-23",
+            "fields": {
+                "customfield_10046": [
+				  {
+					"name": "jira-administrators-2",
+					"groupId": "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764"
+				  },
+				  {
+					"name": "jira-administrators-system-2",
+					"groupId": "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					"self": "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a"
+				  }
+				]
+            }
+        }
+    ]
+}`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]*GroupDetailScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*GroupDetailScheme{
+				"KP-22": {
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+						Name:    "jira-administrators",
+						GroupID: "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					},
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+						Name:    "jira-administrators-system",
+						GroupID: "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					},
+				},
+				"KP-23": {
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+						Name:    "jira-administrators-2",
+						GroupID: "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					},
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+						Name:    "jira-administrators-system-2",
+						GroupID: "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*GroupDetailScheme{
+				"KP-23": {
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+						Name:    "jira-administrators-2",
+						GroupID: "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					},
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+						Name:    "jira-administrators-system-2",
+						GroupID: "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					},
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*GroupDetailScheme{
+				"KP-23": {
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+						Name:    "jira-administrators-2",
+						GroupID: "1da6f895-2b42-423b-8bfb-1e09ee8d7764",
+					},
+					{
+						Self:    "https://ctreminiom.atlassian.net/rest/api/3/group?groupId=be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+						Name:    "jira-administrators-system-2",
+						GroupID: "be9ba0ab-ecdc-445b-9ce6-b95202026c1a",
+					},
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseMultiGroupPickerCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseMultiUserPickerCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": null,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]*UserDetailScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*UserDetailScheme{
+				"KP-22": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+						AccountID:   "5e5f6a63157ed50cd2b9eaca",
+						DisplayName: "Carlos Treminio",
+						Active:      true,
+						TimeZone:    "Asia/Dhaka",
+						AccountType: "atlassian",
+					},
+					{
+						Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+						AccountID:    "5b86be50b8e3cb5895860d6d",
+						DisplayName:  "Carlos Treminio",
+						EmailAddress: "ctreminiom079@gmail.com",
+						Active:       true,
+						TimeZone:     "America/Guatemala",
+						AccountType:  "atlassian",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+						AccountID:   "557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+						DisplayName: "Trello",
+						Active:      true,
+						TimeZone:    "Europe/London",
+						AccountType: "app",
+					},
+				},
+				"KP-23": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+						AccountID:   "5e5f6a63157ed50cd2b9eaca",
+						DisplayName: "Carlos Treminio",
+						Active:      true,
+						TimeZone:    "Asia/Dhaka",
+						AccountType: "atlassian",
+					},
+					{
+						Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+						AccountID:    "5b86be50b8e3cb5895860d6d",
+						DisplayName:  "Carlos Treminio",
+						EmailAddress: "ctreminiom079@gmail.com",
+						Active:       true,
+						TimeZone:     "America/Guatemala",
+						AccountType:  "atlassian",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+						AccountID:   "557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+						DisplayName: "Trello",
+						Active:      true,
+						TimeZone:    "Europe/London",
+						AccountType: "app",
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*UserDetailScheme{
+				"KP-23": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+						AccountID:   "5e5f6a63157ed50cd2b9eaca",
+						DisplayName: "Carlos Treminio",
+						Active:      true,
+						TimeZone:    "Asia/Dhaka",
+						AccountType: "atlassian",
+					},
+					{
+						Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+						AccountID:    "5b86be50b8e3cb5895860d6d",
+						DisplayName:  "Carlos Treminio",
+						EmailAddress: "ctreminiom079@gmail.com",
+						Active:       true,
+						TimeZone:     "America/Guatemala",
+						AccountType:  "atlassian",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+						AccountID:   "557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+						DisplayName: "Trello",
+						Active:      true,
+						TimeZone:    "Europe/London",
+						AccountType: "app",
+					},
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*UserDetailScheme{
+				"KP-23": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+						AccountID:   "5e5f6a63157ed50cd2b9eaca",
+						DisplayName: "Carlos Treminio",
+						Active:      true,
+						TimeZone:    "Asia/Dhaka",
+						AccountType: "atlassian",
+					},
+					{
+						Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+						AccountID:    "5b86be50b8e3cb5895860d6d",
+						DisplayName:  "Carlos Treminio",
+						EmailAddress: "ctreminiom079@gmail.com",
+						Active:       true,
+						TimeZone:     "America/Guatemala",
+						AccountType:  "atlassian",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+						AccountID:   "557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+						DisplayName: "Trello",
+						Active:      true,
+						TimeZone:    "Europe/London",
+						AccountType: "app",
+					},
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseMultiUserPickerCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseCascadingCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10054",
+			  "value": "America",
+			  "id": "10054",
+			  "child": {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10057",
+				"value": "Costa Rica",
+				"id": "10057"
+			  }
+			}
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10054",
+			  "value": "America",
+			  "id": "10054",
+			  "child": {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10057",
+				"value": "Costa Rica",
+				"id": "10057"
+			  }
+			}
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10054",
+			  "value": "America",
+			  "id": "10054",
+			  "child": {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10057",
+				"value": "Costa Rica",
+				"id": "10057"
+			  }
+			}
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]*CascadingSelectScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]*CascadingSelectScheme{
+				"KP-22": {
+					Self:  "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10054",
+					Value: "America",
+					Id:    "10054",
+					Child: &CascadingSelectChildScheme{
+						Self:  "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10057",
+						Value: "Costa Rica",
+						Id:    "10057",
+					},
+				},
+				"KP-23": {
+					Self:  "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10054",
+					Value: "America",
+					Id:    "10054",
+					Child: &CascadingSelectChildScheme{
+						Self:  "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10057",
+						Value: "Costa Rica",
+						Id:    "10057",
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]*CascadingSelectScheme{
+				"KP-22": {
+					Self:  "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10054",
+					Value: "America",
+					Id:    "10054",
+					Child: &CascadingSelectChildScheme{
+						Self:  "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10057",
+						Value: "Costa Rica",
+						Id:    "10057",
+					},
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseCascadingCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseMultiVersionCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":[
+			  {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/version/10000",
+				"id": "10000",
+				"description": "",
+				"name": "Version 00",
+				"archived": false,
+				"released": false,
+				"releaseDate": "2021-02-23"
+			  },
+			  {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/version/10002",
+				"id": "10002",
+				"description": "Version Sandbox description - UPDATED",
+				"name": "Version Sandbox - UPDATED",
+				"archived": false,
+				"released": true,
+				"releaseDate": "2021-03-06"
+			  }
+			]
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+			  {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/version/10000",
+				"id": "10000",
+				"description": "",
+				"name": "Version 00",
+				"archived": false,
+				"released": false,
+				"releaseDate": "2021-02-23"
+			  },
+			  {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/version/10002",
+				"id": "10002",
+				"description": "Version Sandbox description - UPDATED",
+				"name": "Version Sandbox - UPDATED",
+				"archived": false,
+				"released": true,
+				"releaseDate": "2021-03-06"
+			  }
+			]
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":[
+			  {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/version/10000",
+				"id": "10000",
+				"description": "",
+				"name": "Version 00",
+				"archived": false,
+				"released": false,
+				"releaseDate": "2021-02-23"
+			  },
+			  {
+				"self": "https://ctreminiom.atlassian.net/rest/api/3/version/10002",
+				"id": "10002",
+				"description": "Version Sandbox description - UPDATED",
+				"name": "Version Sandbox - UPDATED",
+				"archived": false,
+				"released": true,
+				"releaseDate": "2021-03-06"
+			  }
+			]
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/3/version/10000"
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/3/version/10000"
+         }
+      },
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]*VersionDetailScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*VersionDetailScheme{
+
+				"KP-22": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/version/10000",
+						ID:          "10000",
+						Name:        "Version 00",
+						Archived:    false,
+						Released:    false,
+						ReleaseDate: "2021-02-23",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/version/10002",
+						ID:          "10002",
+						Description: "Version Sandbox description - UPDATED",
+						Name:        "Version Sandbox - UPDATED",
+						Archived:    false,
+						Released:    true,
+						ReleaseDate: "2021-03-06",
+					},
+				},
+				"KP-23": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/version/10000",
+						ID:          "10000",
+						Name:        "Version 00",
+						Archived:    false,
+						Released:    false,
+						ReleaseDate: "2021-02-23",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/version/10002",
+						ID:          "10002",
+						Description: "Version Sandbox description - UPDATED",
+						Name:        "Version Sandbox - UPDATED",
+						Archived:    false,
+						Released:    true,
+						ReleaseDate: "2021-03-06",
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*VersionDetailScheme{
+
+				"KP-22": {
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/version/10000",
+						ID:          "10000",
+						Name:        "Version 00",
+						Archived:    false,
+						Released:    false,
+						ReleaseDate: "2021-02-23",
+					},
+					{
+						Self:        "https://ctreminiom.atlassian.net/rest/api/3/version/10002",
+						ID:          "10002",
+						Description: "Version Sandbox description - UPDATED",
+						Name:        "Version Sandbox - UPDATED",
+						Archived:    false,
+						Released:    true,
+						ReleaseDate: "2021-03-06",
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseMultiVersionCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseUserPickerCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6acefc1fca0af44135f8",
+			  "accountId": "5e5f6acefc1fca0af44135f8",
+			  "emailAddress": "example@example.com",
+			  "avatarUrls": {
+				"48x48": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"24x24": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"16x16": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"32x32": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png"
+			  },
+			  "displayName": "Eduardo Navarro",
+			  "active": true,
+			  "timeZone": "Europe/London",
+			  "accountType": "atlassian"
+			}
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6acefc1fca0af44135f8",
+			  "accountId": "5e5f6acefc1fca0af44135f8",
+			  "emailAddress": "example@example.com",
+			  "avatarUrls": {
+				"48x48": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"24x24": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"16x16": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"32x32": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png"
+			  },
+			  "displayName": "Eduardo Navarro",
+			  "active": true,
+			  "timeZone": "Europe/London",
+			  "accountType": "atlassian"
+			}
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6acefc1fca0af44135f8",
+			  "accountId": "5e5f6acefc1fca0af44135f8",
+			  "emailAddress": "example@example.com",
+			  "avatarUrls": {
+				"48x48": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"24x24": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"16x16": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png",
+				"32x32": "https://secure.gravatar.com/avatar/6c20a29c5ab36b3cbc121782edaadfc9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FEN-4.png"
+			  },
+			  "displayName": "Eduardo Navarro",
+			  "active": true,
+			  "timeZone": "Europe/London",
+			  "accountType": "atlassian"
+			}
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]*UserDetailScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]*UserDetailScheme{
+				"KP-22": {
+					Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6acefc1fca0af44135f8",
+					AccountID:    "5e5f6acefc1fca0af44135f8",
+					EmailAddress: "example@example.com",
+					DisplayName:  "Eduardo Navarro",
+					Active:       true,
+					TimeZone:     "Europe/London",
+					AccountType:  "atlassian",
+				},
+				"KP-23": {
+					Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6acefc1fca0af44135f8",
+					AccountID:    "5e5f6acefc1fca0af44135f8",
+					EmailAddress: "example@example.com",
+					DisplayName:  "Eduardo Navarro",
+					Active:       true,
+					TimeZone:     "Europe/London",
+					AccountType:  "atlassian",
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]*UserDetailScheme{
+				"KP-22": {
+					Self:         "https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6acefc1fca0af44135f8",
+					AccountID:    "5e5f6acefc1fca0af44135f8",
+					EmailAddress: "example@example.com",
+					DisplayName:  "Eduardo Navarro",
+					Active:       true,
+					TimeZone:     "Europe/London",
+					AccountType:  "atlassian",
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseUserPickerCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseStringCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":  "Lorem ipsum dolor sit amet, consetetur sadipscing elitr"
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":  "Lorem ipsum dolor sit amet, consetetur sadipscing elitr"
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":  "Lorem ipsum dolor sit amet, consetetur sadipscing elitr"
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": ["self": "asd"],
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]string
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]string{
+				"KP-22": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr",
+				"KP-23": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr",
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]string{
+				"KP-22": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr",
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseStringCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseStringCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseFloatCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":  4003939
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": 4003939
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": 4003939
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": ["self": "asd"],
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]float64
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]float64{
+				"KP-22": 4003939,
+				"KP-23": 4003939,
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]float64{
+				"KP-22": 4003939,
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseFloatCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseFloatCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseLabelCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":  ["label-1", "label-2"]
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":  ["label-1", "label-2"]
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":  ["label-1", "label-2"]
+         }
+      },
+     {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+   ]
+}
+`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": ["self": "asd"],
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5e5f6a63157ed50cd2b9eaca",
+                  "accountId":"5e5f6a63157ed50cd2b9eaca",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "24x24":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "16x16":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png",
+                     "32x32":"https://secure.gravatar.com/avatar/2e6d2ee8550c63137e196a2890bc25a9?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-4.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"Asia/Dhaka",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=5b86be50b8e3cb5895860d6d",
+                  "accountId":"5b86be50b8e3cb5895860d6d",
+                  "emailAddress":"ctreminiom079@gmail.com",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "24x24":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "16x16":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png",
+                     "32x32":"https://secure.gravatar.com/avatar/b830f79c6cc32dcbcb9842f98cd3d3cd?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FCT-6.png"
+                  },
+                  "displayName":"Carlos Treminio",
+                  "active":true,
+                  "timeZone":"America/Guatemala",
+                  "accountType":"atlassian"
+               },
+               {
+                  "self":"https://ctreminiom.atlassian.net/rest/api/3/user?accountId=557058%3Ad6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "accountId":"557058:d6b5955a-e193-41e1-b051-79cdb0755d68",
+                  "avatarUrls":{
+                     "48x48":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "24x24":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "16x16":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png",
+                     "32x32":"https://secure.gravatar.com/avatar/53e3e37950768a905d53cebdfcbd63e3?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FT-1.png"
+                  },
+                  "displayName":"Trello",
+                  "active":true,
+                  "timeZone":"Europe/London",
+                  "accountType":"app"
+               }
+            ]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]string
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]string{
+				"KP-22": {"label-1", "label-2"},
+				"KP-23": {"label-1", "label-2"},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string][]string{
+				"KP-22": {"label-1", "label-2"},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseLabelCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseLabelCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseLabelCustomFields() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseLabelCustomFields() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseSprintCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":[
+			  {
+				"id": 5,
+				"name": "KP Sprint 3",
+				"state": "active",
+				"boardId": 4,
+				"goal": "",
+				"startDate": "2023-03-04T02:03:16.273Z",
+				"endDate": "2023-03-17T02:03:00.000Z",
+				"completeDate": "2023-03-04T02:03:16.273Z"
+			  }
+			]
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+			  {
+				"id": 5,
+				"name": "KP Sprint 3",
+				"state": "active",
+				"boardId": 4,
+				"goal": "",
+				"startDate": "2023-03-04T02:03:16.273Z",
+				"endDate": "2023-03-17T02:03:00.000Z",
+				"completeDate": "2023-03-04T02:03:16.273Z"
+			  }
+			]
+         }
+      }
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": null,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+			  {
+				"id": 5,
+				"name": "KP Sprint 3",
+				"state": "active",
+				"boardId": 4,
+				"goal": "",
+				"startDate": "2023-03-04T02:03:16.273Z",
+				"endDate": "2023-03-17T02:03:00.000Z",
+				"completeDate": "2023-03-04T02:03:16.273Z"
+			  }
+			]
+         }
+      }
+   ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":"5e5f6a63157ed50cd2b9eaca"
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]*SprintDetailScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*SprintDetailScheme{
+				"KP-22": {
+					{
+						ID:           5,
+						State:        "active",
+						Name:         "KP Sprint 3",
+						StartDate:    "2023-03-04T02:03:16.273Z",
+						EndDate:      "2023-03-17T02:03:00.000Z",
+						CompleteDate: "2023-03-04T02:03:16.273Z",
+						BoardID:      4,
+					},
+				},
+				"KP-23": {
+					{
+						ID:           5,
+						State:        "active",
+						Name:         "KP Sprint 3",
+						StartDate:    "2023-03-04T02:03:16.273Z",
+						EndDate:      "2023-03-17T02:03:00.000Z",
+						CompleteDate: "2023-03-04T02:03:16.273Z",
+						BoardID:      4,
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*SprintDetailScheme{
+				"KP-23": {
+					{
+						ID:           5,
+						State:        "active",
+						Name:         "KP Sprint 3",
+						StartDate:    "2023-03-04T02:03:16.273Z",
+						EndDate:      "2023-03-17T02:03:00.000Z",
+						CompleteDate: "2023-03-04T02:03:16.273Z",
+						BoardID:      4,
+					},
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseSprintCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseSprintCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseSprintCustomFields() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseSprintCustomFields() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseSelectCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
+			  "value": "Scranton 1",
+			  "id": "10058"
+			}
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
+			  "value": "Scranton 1",
+			  "id": "10058"
+			}
+         }
+      }
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": null,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":{
+			  "self": "https://ctreminiom.atlassian.net/rest/api/3/customFieldOption/10058",
+			  "value": "Scranton 1",
+			  "id": "10058"
+			}
+         }
+      }
+   ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":"5e5f6a63157ed50cd2b9eaca"
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]*CustomFieldContextOptionScheme
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]*CustomFieldContextOptionScheme{
+				"KP-22": {
+					ID:    "10058",
+					Value: "Scranton 1",
+				},
+				"KP-23": {
+					ID:    "10058",
+					Value: "Scranton 1",
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]*CustomFieldContextOptionScheme{
+				"KP-23": {
+					ID:    "10058",
+					Value: "Scranton 1",
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseSelectCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseSelectCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseSelectCustomFields() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseSelectCustomFields() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseAssetCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046":[
+			 {
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+				"objectId": "1"
+			  },
+				{
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f2",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+				"objectId": "1"
+			  }
+			]
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+			 {
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+				"objectId": "1"
+			  },
+				{
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f2",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+				"objectId": "1"
+			  }
+			]
+         }
+      }
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": null
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+			 {
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+				"objectId": "1"
+			  },
+				{
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f2",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+				"objectId": "1"
+			  }
+			]
+         }
+      }
+   ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "test"
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046":[
+			 {
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+				"objectId": "1"
+			  },
+				{
+				"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f2",
+				"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+				"objectId": "1"
+			  }
+			]
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]*CustomFieldAssetScheme
+		wantErr bool
+		Err     error
+	}{
+
+		/*
+			"customfield_10046":[
+					 {
+						"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f1",
+						"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+						"objectId": "1"
+					  },
+						{
+						"workspaceId": "5e037d73-1c0a-43ce-adca-f169a42557f2",
+						"id": "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+						"objectId": "1"
+					  }
+					]
+		*/
+
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*CustomFieldAssetScheme{
+				"KP-22": {
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f1",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+						ObjectId:    "1",
+					},
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f2",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+						ObjectId:    "1",
+					},
+				},
+				"KP-23": {
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f1",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+						ObjectId:    "1",
+					},
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f2",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+						ObjectId:    "1",
+					},
+				},
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*CustomFieldAssetScheme{
+				"KP-23": {
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f1",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+						ObjectId:    "1",
+					},
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f2",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+						ObjectId:    "1",
+					},
+				},
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			want: map[string][]*CustomFieldAssetScheme{
+				"KP-23": {
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f1",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:1",
+						ObjectId:    "1",
+					},
+					{
+						WorkspaceId: "5e037d73-1c0a-43ce-adca-f169a42557f2",
+						Id:          "5e037d73-1c0a-43ce-adca-f169a42557f1:2",
+						ObjectId:    "1",
+					},
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseAssetCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseMultiSelectCustomField() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseMultiSelectCustomField() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseMultiSelectCustomField() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseDatePickerCustomFields(t *testing.T) {
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "2023-09-22"
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+             "customfield_10046": "2023-09-23"
+         }
+      }
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": null,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": "2023-09-23"
+         }
+      }
+   ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": 33030303,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": true
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]time.Time
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]time.Time{
+				"KP-22": time.Date(2023, time.September, 22, 0, 0, 0, 0, time.UTC),
+				"KP-23": time.Date(2023, time.September, 23, 0, 0, 0, 0, time.UTC),
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]time.Time{
+				"KP-23": time.Date(2023, time.September, 23, 0, 0, 0, 0, time.UTC),
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseDatePickerCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseSelectCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseSelectCustomFields() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseSelectCustomFields() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
+
+func TestParseDateTimeCustomFields(t *testing.T) {
+
+	mockedTime, err := time.Parse("2006-01-02T15:04:05.000-0700", "2023-07-12T16:00:00.000+0100")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	bufferMocked := bytes.Buffer{}
+	bufferMocked.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": "2023-07-12T16:00:00.000+0100"
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+             "customfield_10046": "2023-07-12T16:00:00.000+0100"
+         }
+      }
+   ]
+}
+`)
+
+	bufferMockedWithNoIssues := bytes.Buffer{}
+	bufferMockedWithNoIssues.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "no_issues": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "no_fields": {
+                "customfield_10046": [
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10046",
+                        "value": "Option 3",
+                        "id": "10046"
+                    },
+                    {
+                        "self": "https://ctreminiom.atlassian.net/rest/api/2/customFieldOption/10047",
+                        "value": "Option 4",
+                        "id": "10047"
+                    }
+                ]
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNoInfo := bytes.Buffer{}
+	bufferMockedWithNoInfo.WriteString(`
+{
+    "expand": "names,schema",
+    "startAt": 0,
+    "maxResults": 50,
+    "total": 1,
+    "data": [
+        {
+            "expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
+            "id": "10035",
+            "self": "https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+            "key": "KP-22",
+            "fields": {
+                "customfield_10046": null
+            }
+        }
+    ]
+}`)
+
+	bufferMockedWithNullValues := bytes.Buffer{}
+	bufferMockedWithNullValues.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": null,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": "2023-07-12T16:00:00.000+0100"
+         }
+      }
+   ]
+}`)
+
+	bufferMockedWithInvalidTypes := bytes.Buffer{}
+	bufferMockedWithInvalidTypes.WriteString(`
+{
+   "expand":"names,schema",
+   "startAt":0,
+   "maxResults":50,
+   "total":1,
+   "issues":[
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-22",
+         "fields":{
+            "customfield_10046": 33030303,
+         }
+      },
+      {
+         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
+         "id":"10035",
+         "self":"https://ctreminiom.atlassian.net/rest/api/2/issue/10035",
+         "key":"KP-23",
+         "fields":{
+            "customfield_10046": true
+         }
+      }
+   ]
+}
+`)
+
+	type args struct {
+		buffer      bytes.Buffer
+		customField string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string]time.Time
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the buffer contains information",
+			args: args{
+				buffer:      bufferMocked,
+				customField: "customfield_10046",
+			},
+			want: map[string]time.Time{
+				"KP-22": mockedTime,
+				"KP-23": mockedTime,
+			},
+
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer does not contain the issues object",
+			args: args{
+				buffer:      bufferMockedWithNoInfo,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoIssuesSliceError,
+		},
+
+		{
+			name: "when the buffer contains null customfields",
+			args: args{
+				buffer:      bufferMockedWithNullValues,
+				customField: "customfield_10046",
+			},
+			want: map[string]time.Time{
+				"KP-23": mockedTime,
+			},
+			wantErr: false,
+		},
+
+		{
+			name: "when the buffer contains invalid types",
+			args: args{
+				buffer:      bufferMockedWithInvalidTypes,
+				customField: "customfield_10046",
+			},
+			wantErr: true,
+			Err:     ErrNoMapValuesError,
+		},
+	}
+	for _, testCase := range tests {
+		t.Run(testCase.name, func(t *testing.T) {
+			got, err := ParseDateTimeCustomFields(testCase.args.buffer, testCase.args.customField)
+			if (err != nil) != testCase.wantErr {
+				t.Errorf("ParseSelectCustomFields() error = %v, wantErr %v", err, testCase.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, testCase.want) {
+				t.Errorf("ParseSelectCustomFields() got = %v, want %v", got, testCase.want)
+			}
+			if !reflect.DeepEqual(err, testCase.Err) {
+				t.Errorf("ParseSelectCustomFields() got = (%v), want (%v)", err, testCase.Err)
+			}
+		})
+	}
+}
diff --git a/pkg/infra/models/sm_request_field_test.go b/pkg/infra/models/sm_request_field_test.go
index e2ee222..97e3658 100644
--- a/pkg/infra/models/sm_request_field_test.go
+++ b/pkg/infra/models/sm_request_field_test.go
@@ -64,7 +64,7 @@ func TestCreateCustomerRequestPayloadScheme_DateTimeCustomField(t *testing.T) {
 				value: time.Time{},
 			},
 			wantErr: true,
-			Err:     ErrNoDateTimeTypeError,
+			Err:     ErrNoDatePickerTypeError,
 		},
 	}
 	for _, tt := range tests {
@@ -155,7 +155,7 @@ func TestCreateCustomerRequestPayloadScheme_DateCustomField(t *testing.T) {
 				value: time.Time{},
 			},
 			wantErr: true,
-			Err:     ErrNoDateTimeTypeError,
+			Err:     ErrNoDatePickerTypeError,
 		},
 	}
 	for _, tt := range tests {