diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 9c048579f7f..f275ddad7ed 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -4145,7 +4145,8 @@ func init() { "closeoutInitiated", "closeoutLocation", "ppmStatus", - "counselingOffice" + "counselingOffice", + "assignedTo" ], "type": "string", "description": "field that results should be sorted by", @@ -4298,6 +4299,12 @@ func init() { "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", "name": "viewAsGBLOC", "in": "query" + }, + { + "type": "string", + "description": "Used to illustrate which user is assigned to this payment request.\n", + "name": "assignedTo", + "in": "query" } ], "responses": { @@ -4386,7 +4393,8 @@ func init() { "originDutyLocation", "destinationDutyLocation", "requestedMoveDate", - "appearedInTooAt" + "appearedInTooAt", + "assignedTo" ], "type": "string", "description": "field that results should be sorted by", @@ -6369,13 +6377,13 @@ func init() { "firstName": { "type": "string" }, - "id": { + "lastName": { + "type": "string" + }, + "officeUserId": { "type": "string", "format": "uuid", "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" - }, - "lastName": { - "type": "string" } } }, @@ -11736,6 +11744,9 @@ func init() { "x-nullable": true, "$ref": "#/definitions/AssignedOfficeUser" }, + "availableOfficeUsers": { + "$ref": "#/definitions/AvailableOfficeUsers" + }, "closeoutInitiated": { "type": "string", "format": "date-time", @@ -11828,9 +11839,6 @@ func init() { "QueueMovesResult": { "type": "object", "properties": { - "availableOfficeUsers": { - "$ref": "#/definitions/AvailableOfficeUsers" - }, "page": { "type": "integer" }, @@ -11853,6 +11861,9 @@ func init() { "type": "number", "format": "double" }, + "availableOfficeUsers": { + "$ref": "#/definitions/AvailableOfficeUsers" + }, "customer": { "$ref": "#/definitions/Customer" }, @@ -11918,9 +11929,6 @@ func init() { "QueuePaymentRequestsResult": { "type": "object", "properties": { - "availableOfficeUsers": { - "$ref": "#/definitions/AvailableOfficeUsers" - }, "page": { "type": "integer" }, @@ -19439,7 +19447,8 @@ func init() { "closeoutInitiated", "closeoutLocation", "ppmStatus", - "counselingOffice" + "counselingOffice", + "assignedTo" ], "type": "string", "description": "field that results should be sorted by", @@ -19592,6 +19601,12 @@ func init() { "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", "name": "viewAsGBLOC", "in": "query" + }, + { + "type": "string", + "description": "Used to illustrate which user is assigned to this payment request.\n", + "name": "assignedTo", + "in": "query" } ], "responses": { @@ -19692,7 +19707,8 @@ func init() { "originDutyLocation", "destinationDutyLocation", "requestedMoveDate", - "appearedInTooAt" + "appearedInTooAt", + "assignedTo" ], "type": "string", "description": "field that results should be sorted by", @@ -22045,13 +22061,13 @@ func init() { "firstName": { "type": "string" }, - "id": { + "lastName": { + "type": "string" + }, + "officeUserId": { "type": "string", "format": "uuid", "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" - }, - "lastName": { - "type": "string" } } }, @@ -27491,6 +27507,9 @@ func init() { "x-nullable": true, "$ref": "#/definitions/AssignedOfficeUser" }, + "availableOfficeUsers": { + "$ref": "#/definitions/AvailableOfficeUsers" + }, "closeoutInitiated": { "type": "string", "format": "date-time", @@ -27583,9 +27602,6 @@ func init() { "QueueMovesResult": { "type": "object", "properties": { - "availableOfficeUsers": { - "$ref": "#/definitions/AvailableOfficeUsers" - }, "page": { "type": "integer" }, @@ -27608,6 +27624,9 @@ func init() { "type": "number", "format": "double" }, + "availableOfficeUsers": { + "$ref": "#/definitions/AvailableOfficeUsers" + }, "customer": { "$ref": "#/definitions/Customer" }, @@ -27673,9 +27692,6 @@ func init() { "QueuePaymentRequestsResult": { "type": "object", "properties": { - "availableOfficeUsers": { - "$ref": "#/definitions/AvailableOfficeUsers" - }, "page": { "type": "integer" }, diff --git a/pkg/gen/ghcapi/ghcoperations/queues/get_moves_queue_parameters.go b/pkg/gen/ghcapi/ghcoperations/queues/get_moves_queue_parameters.go index 9257f37c8ff..3f41b22702b 100644 --- a/pkg/gen/ghcapi/ghcoperations/queues/get_moves_queue_parameters.go +++ b/pkg/gen/ghcapi/ghcoperations/queues/get_moves_queue_parameters.go @@ -519,7 +519,7 @@ func (o *GetMovesQueueParams) bindSort(rawData []string, hasKey bool, formats st // validateSort carries on validations for parameter Sort func (o *GetMovesQueueParams) validateSort(formats strfmt.Registry) error { - if err := validate.EnumCase("sort", "query", *o.Sort, []interface{}{"lastName", "dodID", "emplid", "branch", "locator", "status", "originDutyLocation", "destinationDutyLocation", "requestedMoveDate", "appearedInTooAt"}, true); err != nil { + if err := validate.EnumCase("sort", "query", *o.Sort, []interface{}{"lastName", "dodID", "emplid", "branch", "locator", "status", "originDutyLocation", "destinationDutyLocation", "requestedMoveDate", "appearedInTooAt", "assignedTo"}, true); err != nil { return err } diff --git a/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_parameters.go b/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_parameters.go index 6d1745d74fd..20744a2c85b 100644 --- a/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_parameters.go +++ b/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_parameters.go @@ -34,6 +34,11 @@ type GetServicesCounselingQueueParams struct { // HTTP Request Object HTTPRequest *http.Request `json:"-"` + /*Used to illustrate which user is assigned to this payment request. + + In: query + */ + AssignedTo *string /*filters by the branch of the move's service member In: query */ @@ -143,6 +148,11 @@ func (o *GetServicesCounselingQueueParams) BindRequest(r *http.Request, route *m qs := runtime.Values(r.URL.Query()) + qAssignedTo, qhkAssignedTo, _ := qs.GetOK("assignedTo") + if err := o.bindAssignedTo(qAssignedTo, qhkAssignedTo, route.Formats); err != nil { + res = append(res, err) + } + qBranch, qhkBranch, _ := qs.GetOK("branch") if err := o.bindBranch(qBranch, qhkBranch, route.Formats); err != nil { res = append(res, err) @@ -263,6 +273,24 @@ func (o *GetServicesCounselingQueueParams) BindRequest(r *http.Request, route *m return nil } +// bindAssignedTo binds and validates parameter AssignedTo from query. +func (o *GetServicesCounselingQueueParams) bindAssignedTo(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: false + // AllowEmptyValue: false + + if raw == "" { // empty values pass all other validations + return nil + } + o.AssignedTo = &raw + + return nil +} + // bindBranch binds and validates parameter Branch from query. func (o *GetServicesCounselingQueueParams) bindBranch(rawData []string, hasKey bool, formats strfmt.Registry) error { var raw string @@ -723,7 +751,7 @@ func (o *GetServicesCounselingQueueParams) bindSort(rawData []string, hasKey boo // validateSort carries on validations for parameter Sort func (o *GetServicesCounselingQueueParams) validateSort(formats strfmt.Registry) error { - if err := validate.EnumCase("sort", "query", *o.Sort, []interface{}{"lastName", "dodID", "emplid", "branch", "locator", "status", "requestedMoveDate", "submittedAt", "originGBLOC", "originDutyLocation", "destinationDutyLocation", "ppmType", "closeoutInitiated", "closeoutLocation", "ppmStatus", "counselingOffice"}, true); err != nil { + if err := validate.EnumCase("sort", "query", *o.Sort, []interface{}{"lastName", "dodID", "emplid", "branch", "locator", "status", "requestedMoveDate", "submittedAt", "originGBLOC", "originDutyLocation", "destinationDutyLocation", "ppmType", "closeoutInitiated", "closeoutLocation", "ppmStatus", "counselingOffice", "assignedTo"}, true); err != nil { return err } diff --git a/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_urlbuilder.go b/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_urlbuilder.go index c9549f94ac2..5f1d7d96c2c 100644 --- a/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_urlbuilder.go +++ b/pkg/gen/ghcapi/ghcoperations/queues/get_services_counseling_queue_urlbuilder.go @@ -16,6 +16,7 @@ import ( // GetServicesCounselingQueueURL generates an URL for the get services counseling queue operation type GetServicesCounselingQueueURL struct { + AssignedTo *string Branch *string CloseoutInitiated *strfmt.DateTime CloseoutLocation *string @@ -74,6 +75,14 @@ func (o *GetServicesCounselingQueueURL) Build() (*url.URL, error) { qs := make(url.Values) + var assignedToQ string + if o.AssignedTo != nil { + assignedToQ = *o.AssignedTo + } + if assignedToQ != "" { + qs.Set("assignedTo", assignedToQ) + } + var branchQ string if o.Branch != nil { branchQ = *o.Branch diff --git a/pkg/gen/ghcmessages/assigned_office_user.go b/pkg/gen/ghcmessages/assigned_office_user.go index 60d6a5b687a..596b4f192f5 100644 --- a/pkg/gen/ghcmessages/assigned_office_user.go +++ b/pkg/gen/ghcmessages/assigned_office_user.go @@ -22,20 +22,20 @@ type AssignedOfficeUser struct { // first name FirstName string `json:"firstName,omitempty"` - // id - // Example: c56a4180-65aa-42ec-a945-5fd21dec0538 - // Format: uuid - ID strfmt.UUID `json:"id,omitempty"` - // last name LastName string `json:"lastName,omitempty"` + + // office user Id + // Example: c56a4180-65aa-42ec-a945-5fd21dec0538 + // Format: uuid + OfficeUserID strfmt.UUID `json:"officeUserId,omitempty"` } // Validate validates this assigned office user func (m *AssignedOfficeUser) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateID(formats); err != nil { + if err := m.validateOfficeUserID(formats); err != nil { res = append(res, err) } @@ -45,12 +45,12 @@ func (m *AssignedOfficeUser) Validate(formats strfmt.Registry) error { return nil } -func (m *AssignedOfficeUser) validateID(formats strfmt.Registry) error { - if swag.IsZero(m.ID) { // not required +func (m *AssignedOfficeUser) validateOfficeUserID(formats strfmt.Registry) error { + if swag.IsZero(m.OfficeUserID) { // not required return nil } - if err := validate.FormatOf("id", "body", "uuid", m.ID.String(), formats); err != nil { + if err := validate.FormatOf("officeUserId", "body", "uuid", m.OfficeUserID.String(), formats); err != nil { return err } diff --git a/pkg/gen/ghcmessages/queue_move.go b/pkg/gen/ghcmessages/queue_move.go index f7c831bff29..ba4c5370b52 100644 --- a/pkg/gen/ghcmessages/queue_move.go +++ b/pkg/gen/ghcmessages/queue_move.go @@ -27,6 +27,9 @@ type QueueMove struct { // assigned to AssignedTo *AssignedOfficeUser `json:"assignedTo,omitempty"` + // available office users + AvailableOfficeUsers AvailableOfficeUsers `json:"availableOfficeUsers,omitempty"` + // closeout initiated // Format: date-time CloseoutInitiated *strfmt.DateTime `json:"closeoutInitiated,omitempty"` @@ -107,6 +110,10 @@ func (m *QueueMove) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateAvailableOfficeUsers(formats); err != nil { + res = append(res, err) + } + if err := m.validateCloseoutInitiated(formats); err != nil { res = append(res, err) } @@ -204,6 +211,23 @@ func (m *QueueMove) validateAssignedTo(formats strfmt.Registry) error { return nil } +func (m *QueueMove) validateAvailableOfficeUsers(formats strfmt.Registry) error { + if swag.IsZero(m.AvailableOfficeUsers) { // not required + return nil + } + + if err := m.AvailableOfficeUsers.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("availableOfficeUsers") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("availableOfficeUsers") + } + return err + } + + return nil +} + func (m *QueueMove) validateCloseoutInitiated(formats strfmt.Registry) error { if swag.IsZero(m.CloseoutInitiated) { // not required return nil @@ -472,6 +496,10 @@ func (m *QueueMove) ContextValidate(ctx context.Context, formats strfmt.Registry res = append(res, err) } + if err := m.contextValidateAvailableOfficeUsers(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateCustomer(ctx, formats); err != nil { res = append(res, err) } @@ -531,6 +559,20 @@ func (m *QueueMove) contextValidateAssignedTo(ctx context.Context, formats strfm return nil } +func (m *QueueMove) contextValidateAvailableOfficeUsers(ctx context.Context, formats strfmt.Registry) error { + + if err := m.AvailableOfficeUsers.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("availableOfficeUsers") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("availableOfficeUsers") + } + return err + } + + return nil +} + func (m *QueueMove) contextValidateCustomer(ctx context.Context, formats strfmt.Registry) error { if m.Customer != nil { diff --git a/pkg/gen/ghcmessages/queue_moves_result.go b/pkg/gen/ghcmessages/queue_moves_result.go index c4ebe97ec54..a0117f55989 100644 --- a/pkg/gen/ghcmessages/queue_moves_result.go +++ b/pkg/gen/ghcmessages/queue_moves_result.go @@ -18,9 +18,6 @@ import ( // swagger:model QueueMovesResult type QueueMovesResult struct { - // available office users - AvailableOfficeUsers AvailableOfficeUsers `json:"availableOfficeUsers,omitempty"` - // page Page int64 `json:"page,omitempty"` @@ -38,10 +35,6 @@ type QueueMovesResult struct { func (m *QueueMovesResult) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateAvailableOfficeUsers(formats); err != nil { - res = append(res, err) - } - if err := m.validateQueueMoves(formats); err != nil { res = append(res, err) } @@ -52,23 +45,6 @@ func (m *QueueMovesResult) Validate(formats strfmt.Registry) error { return nil } -func (m *QueueMovesResult) validateAvailableOfficeUsers(formats strfmt.Registry) error { - if swag.IsZero(m.AvailableOfficeUsers) { // not required - return nil - } - - if err := m.AvailableOfficeUsers.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("availableOfficeUsers") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("availableOfficeUsers") - } - return err - } - - return nil -} - func (m *QueueMovesResult) validateQueueMoves(formats strfmt.Registry) error { if swag.IsZero(m.QueueMoves) { // not required return nil @@ -90,10 +66,6 @@ func (m *QueueMovesResult) validateQueueMoves(formats strfmt.Registry) error { func (m *QueueMovesResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := m.contextValidateAvailableOfficeUsers(ctx, formats); err != nil { - res = append(res, err) - } - if err := m.contextValidateQueueMoves(ctx, formats); err != nil { res = append(res, err) } @@ -104,20 +76,6 @@ func (m *QueueMovesResult) ContextValidate(ctx context.Context, formats strfmt.R return nil } -func (m *QueueMovesResult) contextValidateAvailableOfficeUsers(ctx context.Context, formats strfmt.Registry) error { - - if err := m.AvailableOfficeUsers.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("availableOfficeUsers") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("availableOfficeUsers") - } - return err - } - - return nil -} - func (m *QueueMovesResult) contextValidateQueueMoves(ctx context.Context, formats strfmt.Registry) error { if err := m.QueueMoves.ContextValidate(ctx, formats); err != nil { diff --git a/pkg/gen/ghcmessages/queue_payment_request.go b/pkg/gen/ghcmessages/queue_payment_request.go index 10e354e5081..737d1198f5d 100644 --- a/pkg/gen/ghcmessages/queue_payment_request.go +++ b/pkg/gen/ghcmessages/queue_payment_request.go @@ -22,6 +22,9 @@ type QueuePaymentRequest struct { // Days since the payment request has been requested. Decimal representation will allow more accurate sorting. Age float64 `json:"age,omitempty"` + // available office users + AvailableOfficeUsers AvailableOfficeUsers `json:"availableOfficeUsers,omitempty"` + // customer Customer *Customer `json:"customer,omitempty"` @@ -68,6 +71,10 @@ type QueuePaymentRequest struct { func (m *QueuePaymentRequest) Validate(formats strfmt.Registry) error { var res []error + if err := m.validateAvailableOfficeUsers(formats); err != nil { + res = append(res, err) + } + if err := m.validateCustomer(formats); err != nil { res = append(res, err) } @@ -114,6 +121,23 @@ func (m *QueuePaymentRequest) Validate(formats strfmt.Registry) error { return nil } +func (m *QueuePaymentRequest) validateAvailableOfficeUsers(formats strfmt.Registry) error { + if swag.IsZero(m.AvailableOfficeUsers) { // not required + return nil + } + + if err := m.AvailableOfficeUsers.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("availableOfficeUsers") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("availableOfficeUsers") + } + return err + } + + return nil +} + func (m *QueuePaymentRequest) validateCustomer(formats strfmt.Registry) error { if swag.IsZero(m.Customer) { // not required return nil @@ -269,6 +293,10 @@ func (m *QueuePaymentRequest) validateSubmittedAt(formats strfmt.Registry) error func (m *QueuePaymentRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error + if err := m.contextValidateAvailableOfficeUsers(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateCustomer(ctx, formats); err != nil { res = append(res, err) } @@ -295,6 +323,20 @@ func (m *QueuePaymentRequest) ContextValidate(ctx context.Context, formats strfm return nil } +func (m *QueuePaymentRequest) contextValidateAvailableOfficeUsers(ctx context.Context, formats strfmt.Registry) error { + + if err := m.AvailableOfficeUsers.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("availableOfficeUsers") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("availableOfficeUsers") + } + return err + } + + return nil +} + func (m *QueuePaymentRequest) contextValidateCustomer(ctx context.Context, formats strfmt.Registry) error { if m.Customer != nil { diff --git a/pkg/gen/ghcmessages/queue_payment_requests_result.go b/pkg/gen/ghcmessages/queue_payment_requests_result.go index 3516bfe634b..be3af16ade8 100644 --- a/pkg/gen/ghcmessages/queue_payment_requests_result.go +++ b/pkg/gen/ghcmessages/queue_payment_requests_result.go @@ -18,9 +18,6 @@ import ( // swagger:model QueuePaymentRequestsResult type QueuePaymentRequestsResult struct { - // available office users - AvailableOfficeUsers AvailableOfficeUsers `json:"availableOfficeUsers,omitempty"` - // page Page int64 `json:"page,omitempty"` @@ -38,10 +35,6 @@ type QueuePaymentRequestsResult struct { func (m *QueuePaymentRequestsResult) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateAvailableOfficeUsers(formats); err != nil { - res = append(res, err) - } - if err := m.validateQueuePaymentRequests(formats); err != nil { res = append(res, err) } @@ -52,23 +45,6 @@ func (m *QueuePaymentRequestsResult) Validate(formats strfmt.Registry) error { return nil } -func (m *QueuePaymentRequestsResult) validateAvailableOfficeUsers(formats strfmt.Registry) error { - if swag.IsZero(m.AvailableOfficeUsers) { // not required - return nil - } - - if err := m.AvailableOfficeUsers.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("availableOfficeUsers") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("availableOfficeUsers") - } - return err - } - - return nil -} - func (m *QueuePaymentRequestsResult) validateQueuePaymentRequests(formats strfmt.Registry) error { if swag.IsZero(m.QueuePaymentRequests) { // not required return nil @@ -90,10 +66,6 @@ func (m *QueuePaymentRequestsResult) validateQueuePaymentRequests(formats strfmt func (m *QueuePaymentRequestsResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := m.contextValidateAvailableOfficeUsers(ctx, formats); err != nil { - res = append(res, err) - } - if err := m.contextValidateQueuePaymentRequests(ctx, formats); err != nil { res = append(res, err) } @@ -104,20 +76,6 @@ func (m *QueuePaymentRequestsResult) ContextValidate(ctx context.Context, format return nil } -func (m *QueuePaymentRequestsResult) contextValidateAvailableOfficeUsers(ctx context.Context, formats strfmt.Registry) error { - - if err := m.AvailableOfficeUsers.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("availableOfficeUsers") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("availableOfficeUsers") - } - return err - } - - return nil -} - func (m *QueuePaymentRequestsResult) contextValidateQueuePaymentRequests(ctx context.Context, formats strfmt.Registry) error { if err := m.QueuePaymentRequests.ContextValidate(ctx, formats); err != nil { diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 63521590ca1..79c46d780fd 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -54,9 +54,9 @@ func OfficeUser(officeUser *models.OfficeUser) *ghcmessages.LockedOfficeUser { func AssignedOfficeUser(officeUser *models.OfficeUser) *ghcmessages.AssignedOfficeUser { if officeUser != nil { payload := ghcmessages.AssignedOfficeUser{ - ID: strfmt.UUID(officeUser.ID.String()), - FirstName: officeUser.FirstName, - LastName: officeUser.LastName, + OfficeUserID: strfmt.UUID(officeUser.ID.String()), + FirstName: officeUser.FirstName, + LastName: officeUser.LastName, } return &payload } @@ -2034,7 +2034,7 @@ func QueueAvailableOfficeUsers(officeUsers []models.OfficeUser) *ghcmessages.Ava } // QueueMoves payload -func QueueMoves(moves []models.Move) *ghcmessages.QueueMoves { +func QueueMoves(moves []models.Move, officeUsers []models.OfficeUser) *ghcmessages.QueueMoves { queueMoves := make(ghcmessages.QueueMoves, len(moves)) for i, move := range moves { customer := move.Orders.ServiceMember @@ -2116,6 +2116,7 @@ func QueueMoves(moves []models.Move) *ghcmessages.QueueMoves { PpmStatus: ghcmessages.PPMStatus(ppmStatus), CounselingOffice: &transportationOffice, AssignedTo: AssignedOfficeUser(move.SCAssignedUser), + AvailableOfficeUsers: *QueueAvailableOfficeUsers(officeUsers), } } return &queueMoves @@ -2184,7 +2185,7 @@ func queuePaymentRequestStatus(paymentRequest models.PaymentRequest) string { } // QueuePaymentRequests payload -func QueuePaymentRequests(paymentRequests *models.PaymentRequests) *ghcmessages.QueuePaymentRequests { +func QueuePaymentRequests(paymentRequests *models.PaymentRequests, officeUsers []models.OfficeUser) *ghcmessages.QueuePaymentRequests { queuePaymentRequests := make(ghcmessages.QueuePaymentRequests, len(*paymentRequests)) for i, paymentRequest := range *paymentRequests { @@ -2208,6 +2209,7 @@ func QueuePaymentRequests(paymentRequests *models.PaymentRequests) *ghcmessages. OrderType: (*string)(orders.OrdersType.Pointer()), LockedByOfficeUserID: handlers.FmtUUIDPtr(moveTaskOrder.LockedByOfficeUserID), LockExpiresAt: handlers.FmtDateTimePtr(moveTaskOrder.LockExpiresAt), + AvailableOfficeUsers: *QueueAvailableOfficeUsers(officeUsers), } if orders.DepartmentIndicator != nil { diff --git a/pkg/handlers/ghcapi/move_test.go b/pkg/handlers/ghcapi/move_test.go index 28a957f81a0..999f5393c77 100644 --- a/pkg/handlers/ghcapi/move_test.go +++ b/pkg/handlers/ghcapi/move_test.go @@ -20,7 +20,6 @@ import ( "github.com/transcom/mymove/pkg/services" movelocker "github.com/transcom/mymove/pkg/services/lock_move" "github.com/transcom/mymove/pkg/services/mocks" - move "github.com/transcom/mymove/pkg/services/move" moveservice "github.com/transcom/mymove/pkg/services/move" officeuser "github.com/transcom/mymove/pkg/services/office_user" transportationoffice "github.com/transcom/mymove/pkg/services/transportation_office" @@ -707,7 +706,7 @@ func (suite *HandlerSuite) TestUpdateMoveCloseoutOfficeHandler() { func (suite *HandlerSuite) TestUploadAdditionalDocumentsHander() { fakeS3 := storageTest.NewFakeS3Storage(true) uploadCreator := upload.NewUploadCreator(fakeS3) - additionalDocumentsUploader := move.NewMoveAdditionalDocumentsUploader(uploadCreator) + additionalDocumentsUploader := moveservice.NewMoveAdditionalDocumentsUploader(uploadCreator) setupRequestAndParams := func(move models.Move) *moveops.UploadAdditionalDocumentsParams { endpoint := fmt.Sprintf("/moves/%v/upload_additional_documents", move.ID) @@ -805,7 +804,7 @@ func (suite *HandlerSuite) TestUpdateAssignedOfficeUserHandler() { payload := response.(*moveops.UpdateAssignedOfficeUserOK).Payload suite.NoError(payload.Validate(strfmt.Default)) - suite.Equal(officeUserID, payload.SCAssignedUser.ID) + suite.Equal(officeUserID, payload.SCAssignedUser.OfficeUserID) }) suite.Run("Successful update of a move's TOO", func() { req, handler, move, officeUser := setupTestData() @@ -828,7 +827,7 @@ func (suite *HandlerSuite) TestUpdateAssignedOfficeUserHandler() { payload := response.(*moveops.UpdateAssignedOfficeUserOK).Payload suite.NoError(payload.Validate(strfmt.Default)) - suite.Equal(officeUserID, payload.TOOAssignedUser.ID) + suite.Equal(officeUserID, payload.TOOAssignedUser.OfficeUserID) }) suite.Run("Successful update of a move's TIO", func() { req, handler, move, officeUser := setupTestData() @@ -851,7 +850,7 @@ func (suite *HandlerSuite) TestUpdateAssignedOfficeUserHandler() { payload := response.(*moveops.UpdateAssignedOfficeUserOK).Payload suite.NoError(payload.Validate(strfmt.Default)) - suite.Equal(officeUserID, payload.TIOAssignedUser.ID) + suite.Equal(officeUserID, payload.TIOAssignedUser.OfficeUserID) }) suite.Run("Successful unassign of an office user", func() { move = factory.BuildMove(suite.DB(), nil, nil) diff --git a/pkg/handlers/ghcapi/mto_service_items_test.go b/pkg/handlers/ghcapi/mto_service_items_test.go index 069f7d1ea91..3b0b3e74d1b 100644 --- a/pkg/handlers/ghcapi/mto_service_items_test.go +++ b/pkg/handlers/ghcapi/mto_service_items_test.go @@ -24,7 +24,6 @@ import ( "github.com/transcom/mymove/pkg/services/ghcrateengine" mobilehomeshipment "github.com/transcom/mymove/pkg/services/mobile_home_shipment" "github.com/transcom/mymove/pkg/services/mocks" - moverouter "github.com/transcom/mymove/pkg/services/move" moveservices "github.com/transcom/mymove/pkg/services/move" mtoserviceitem "github.com/transcom/mymove/pkg/services/mto_service_item" mtoshipment "github.com/transcom/mymove/pkg/services/mto_shipment" @@ -555,7 +554,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { } fetcher := fetch.NewFetcher(queryBuilder) - moveRouter := moverouter.NewMoveRouter() + moveRouter := moveservices.NewMoveRouter() shipmentFetcher := mtoshipment.NewMTOShipmentFetcher() addressCreator := address.NewAddressCreator() planner := &routemocks.Planner{} @@ -594,7 +593,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { // by the handler is working as expected. suite.Run("Successful status update of MTO service item and event trigger", func() { queryBuilder := query.NewQueryBuilder() - moveRouter := moverouter.NewMoveRouter() + moveRouter := moveservices.NewMoveRouter() shipmentFetcher := mtoshipment.NewMTOShipmentFetcher() mtoServiceItem, availableMove := suite.createServiceItem() requestUser := factory.BuildUser(nil, nil, nil) diff --git a/pkg/handlers/ghcapi/queues.go b/pkg/handlers/ghcapi/queues.go index 8178ddb8515..7aba9de57ed 100644 --- a/pkg/handlers/ghcapi/queues.go +++ b/pkg/handlers/ghcapi/queues.go @@ -133,15 +133,13 @@ func (h GetMovesQueueHandler) Handle(params queues.GetMovesQueueParams) middlewa } } - queueMoves := payloads.QueueMoves(moves) - availableOfficeUsers := payloads.QueueAvailableOfficeUsers(officeUsers) + queueMoves := payloads.QueueMoves(moves, officeUsers) result := &ghcmessages.QueueMovesResult{ - Page: *ListOrderParams.Page, - PerPage: *ListOrderParams.PerPage, - TotalCount: int64(count), - QueueMoves: *queueMoves, - AvailableOfficeUsers: *availableOfficeUsers, + Page: *ListOrderParams.Page, + PerPage: *ListOrderParams.PerPage, + TotalCount: int64(count), + QueueMoves: *queueMoves, } return queues.NewGetMovesQueueOK().WithPayload(result), nil @@ -308,15 +306,13 @@ func (h GetPaymentRequestsQueueHandler) Handle( } } - queuePaymentRequests := payloads.QueuePaymentRequests(paymentRequests) - availableOfficeUsers := payloads.QueueAvailableOfficeUsers(officeUsers) + queuePaymentRequests := payloads.QueuePaymentRequests(paymentRequests, officeUsers) result := &ghcmessages.QueuePaymentRequestsResult{ TotalCount: int64(count), Page: int64(*listPaymentRequestParams.Page), PerPage: int64(*listPaymentRequestParams.PerPage), QueuePaymentRequests: *queuePaymentRequests, - AvailableOfficeUsers: *availableOfficeUsers, } return queues.NewGetPaymentRequestsQueueOK().WithPayload(result), nil @@ -368,6 +364,7 @@ func (h GetServicesCounselingQueueHandler) Handle( OrderType: params.OrderType, PPMStatus: params.PpmStatus, CounselingOffice: params.CounselingOffice, + SCAssignedUser: params.AssignedTo, } if params.NeedsPPMCloseout != nil && *params.NeedsPPMCloseout { @@ -445,15 +442,13 @@ func (h GetServicesCounselingQueueHandler) Handle( } } - queueMoves := payloads.QueueMoves(moves) - availableOfficeUsers := payloads.QueueAvailableOfficeUsers(officeUsers) + queueMoves := payloads.QueueMoves(moves, officeUsers) result := &ghcmessages.QueueMovesResult{ - Page: *ListOrderParams.Page, - PerPage: *ListOrderParams.PerPage, - TotalCount: int64(count), - QueueMoves: *queueMoves, - AvailableOfficeUsers: *availableOfficeUsers, + Page: *ListOrderParams.Page, + PerPage: *ListOrderParams.PerPage, + TotalCount: int64(count), + QueueMoves: *queueMoves, } return queues.NewGetServicesCounselingQueueOK().WithPayload(result), nil diff --git a/pkg/handlers/ghcapi/queues_test.go b/pkg/handlers/ghcapi/queues_test.go index 4cc6aaaa1da..fbace4c29d8 100644 --- a/pkg/handlers/ghcapi/queues_test.go +++ b/pkg/handlers/ghcapi/queues_test.go @@ -91,8 +91,8 @@ func (suite *HandlerSuite) TestGetMoveQueuesHandler() { // Validate outgoing payload suite.NoError(payload.Validate(strfmt.Default)) - suite.Len(payload.AvailableOfficeUsers, 1) - suite.Equal(payload.AvailableOfficeUsers[0].OfficeUserID.String(), officeUser.ID.String()) + suite.Len(payload.QueueMoves[0].AvailableOfficeUsers, 1) + suite.Equal(payload.QueueMoves[0].AvailableOfficeUsers[0].OfficeUserID.String(), officeUser.ID.String()) order := hhgMove.Orders result := payload.QueueMoves[0] @@ -1066,8 +1066,8 @@ func (suite *HandlerSuite) TestGetPaymentRequestsQueueHandler() { suite.NoError(payload.Validate(strfmt.Default)) suite.Len(payload.QueuePaymentRequests, 1) - suite.Len(payload.AvailableOfficeUsers, 1) - suite.Equal(payload.AvailableOfficeUsers[0].OfficeUserID.String(), officeUser.ID.String()) + suite.Len(payload.QueuePaymentRequests[0].AvailableOfficeUsers, 1) + suite.Equal(payload.QueuePaymentRequests[0].AvailableOfficeUsers[0].OfficeUserID.String(), officeUser.ID.String()) paymentRequest := *payload.QueuePaymentRequests[0] @@ -1520,8 +1520,8 @@ func (suite *HandlerSuite) TestGetServicesCounselingQueueHandler() { result1 := payload.QueueMoves[0] result2 := payload.QueueMoves[1] - suite.Len(payload.AvailableOfficeUsers, 1) - suite.Equal(subtestData.officeUser.ID.String(), payload.AvailableOfficeUsers[0].OfficeUserID.String()) + suite.Len(payload.QueueMoves[0].AvailableOfficeUsers, 1) + suite.Equal(subtestData.officeUser.ID.String(), payload.QueueMoves[0].AvailableOfficeUsers[0].OfficeUserID.String()) suite.Len(payload.QueueMoves, 2) suite.Equal(order.ServiceMember.ID.String(), result1.Customer.ID.String()) diff --git a/pkg/services/order.go b/pkg/services/order.go index 7a133fe0bae..5ecac664a7a 100644 --- a/pkg/services/order.go +++ b/pkg/services/order.go @@ -69,4 +69,5 @@ type ListOrderParams struct { PPMStatus *string ViewAsGBLOC *string CounselingOffice *string + SCAssignedUser *string } diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 3b1489d2f6f..cc1277ba247 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -116,10 +116,12 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid closeoutLocationQuery := closeoutLocationFilter(params.CloseoutLocation, ppmCloseoutGblocs) ppmTypeQuery := ppmTypeFilter(params.PPMType) ppmStatusQuery := ppmStatusFilter(params.PPMStatus) + SCAssignedUserQuery := SCAssignedUserFilter(params.SCAssignedUser) sortOrderQuery := sortOrder(params.Sort, params.Order, ppmCloseoutGblocs) counselingQuery := counselingOfficeFilter(params.CounselingOffice) // Adding to an array so we can iterate over them and apply the filters after the query structure is set below - options := [18]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, lastNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, counselingQuery} + options := [19]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, lastNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, SCAssignedUserQuery, counselingQuery} + var query *pop.Query if ppmCloseoutGblocs { query = appCtx.DB().Q().Scope(utilities.ExcludeDeletedScope(models.MTOShipment{})).EagerPreload( @@ -157,8 +159,8 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid "MTOShipments.PPMShipment", "CloseoutOffice", "LockedByOfficeUser", - "SCAssignedUser", "CounselingOffice", + "SCAssignedUser", ).InnerJoin("orders", "orders.id = moves.orders_id"). InnerJoin("service_members", "orders.service_member_id = service_members.id"). InnerJoin("mto_shipments", "moves.id = mto_shipments.move_id"). @@ -171,12 +173,12 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid LeftJoin("duty_locations as dest_dl", "dest_dl.id = orders.new_duty_location_id"). LeftJoin("office_users", "office_users.id = moves.locked_by"). LeftJoin("transportation_offices", "moves.counseling_transportation_office_id = transportation_offices.id"). + LeftJoin("office_users as assigned_user", "moves.sc_assigned_id = assigned_user.id"). Where("show = ?", models.BoolPointer(true)) if !privileges.HasPrivilege(models.PrivilegeTypeSafety) { query.Where("orders.orders_type != (?)", "SAFETY") } - if params.NeedsPPMCloseout != nil { if *params.NeedsPPMCloseout { query.InnerJoin("ppm_shipments", "ppm_shipments.shipment_id = mto_shipments.id"). @@ -236,6 +238,9 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid if params.Sort != nil && *params.Sort == "counselingOffice" { groupByColumms = append(groupByColumms, "transportation_offices.id") } + if params.Sort != nil && *params.Sort == "assignedTo" { + groupByColumms = append(groupByColumms, "assigned_user.last_name", "assigned_user.first_name") + } err = query.GroupBy("moves.id", groupByColumms...).Paginate(int(*params.Page), int(*params.PerPage)).All(&moves) if err != nil { @@ -621,6 +626,13 @@ func ppmStatusFilter(ppmStatus *string) QueryOption { } } } +func SCAssignedUserFilter(scAssigned *string) QueryOption { + return func(query *pop.Query) { + if scAssigned != nil { + query.Where("f_unaccent(lower(?)) % searchable_full_name(assigned_user.first_name, assigned_user.last_name)", *scAssigned) + } + } +} func closeoutLocationFilter(closeoutLocation *string, ppmCloseoutGblocs bool) QueryOption { return func(query *pop.Query) { @@ -703,6 +715,7 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption "closeoutLocation": "closeout_to.name", "closeoutInitiated": "MAX(ppm_shipments.submitted_at)", "counselingOffice": "transportation_offices.name", + "assignedTo": "assigned_user.last_name,assigned_user.first_name", } return func(query *pop.Query) { @@ -716,6 +729,8 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption if sortTerm, ok := parameters[*sort]; ok { if *sort == "lastName" { query.Order(fmt.Sprintf("service_members.last_name %s, service_members.first_name %s", *order, *order)) + } else if *sort == "assignedTo" { + query.Order(fmt.Sprintf("assigned_user.last_name %s, assigned_user.first_name %s", *order, *order)) } else { query.Order(fmt.Sprintf("%s %s", sortTerm, *order)) } diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index f6956d7fd87..20b9fa04166 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -1,6 +1,7 @@ package order import ( + "fmt" "time" "github.com/gofrs/uuid" @@ -10,6 +11,7 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services" + moveservice "github.com/transcom/mymove/pkg/services/move" "github.com/transcom/mymove/pkg/testdatagen" ) @@ -74,6 +76,7 @@ func (suite *OrderServiceSuite) TestListOrders() { agfmPostalCode := "06001" setupTestData := func() (models.OfficeUser, models.Move, auth.Session) { + // Make an office user → GBLOC X officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) session := auth.Session{ @@ -575,7 +578,41 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(createdPPM.Shipment.MoveTaskOrder.Locator, moves[0].Locator) }) } +func (suite *OrderServiceSuite) TestListOrderWithAssignedUserSingle() { + // Under test: ListOrders + // Set up: Make a move, assign one to an SC office user + // Expected outcome: Only the one move with the assigned user should be returned + assignedOfficeUserUpdater := moveservice.NewAssignedOfficeUserUpdater(moveservice.NewMoveFetcher()) + scUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeServicesCounselor}) + var orderFetcherTest orderFetcher + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: scUser.User.Roles, + OfficeUserID: scUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + appCtx := suite.AppContextWithSessionForTest(&session) + createdMove := factory.BuildMoveWithShipment(suite.DB(), nil, nil) + createdMove.SCAssignedID = &scUser.ID + createdMove.SCAssignedUser = &scUser + _, updateError := assignedOfficeUserUpdater.UpdateAssignedOfficeUser(appCtx, createdMove.ID, &scUser, roles.RoleTypeServicesCounselor) + + searchString := fmt.Sprintf("%s, %s", scUser.LastName, scUser.FirstName) + moves, _, err := orderFetcherTest.ListOrders(suite.AppContextWithSessionForTest(&session), scUser.ID, &services.ListOrderParams{ + SCAssignedUser: &searchString, + }) + + suite.FatalNoError(err) + suite.FatalNoError(updateError) + suite.Equal(1, len(moves)) + suite.Equal(moves[0].SCAssignedID, createdMove.SCAssignedID) + suite.Equal(createdMove.SCAssignedUser.ID, moves[0].SCAssignedUser.ID) + suite.Equal(createdMove.SCAssignedUser.FirstName, moves[0].SCAssignedUser.FirstName) + suite.Equal(createdMove.SCAssignedUser.LastName, moves[0].SCAssignedUser.LastName) +} func (suite *OrderServiceSuite) TestListOrdersUSMCGBLOC() { orderFetcher := NewOrderFetcher() diff --git a/src/components/Table/TableQueue.jsx b/src/components/Table/TableQueue.jsx index ef0b9091bc8..5114bde4bc5 100644 --- a/src/components/Table/TableQueue.jsx +++ b/src/components/Table/TableQueue.jsx @@ -23,7 +23,6 @@ import { getTableQueueSortParamSessionStorageValue, getSelectionOptionLabel, } from 'components/Table/utils'; -import { formatAvailableOfficeUsers } from 'utils/queues'; const defaultPageSize = 20; const defaultPage = 1; @@ -50,8 +49,6 @@ const TableQueue = ({ csvExportQueueFetcherKey, sessionStorageKey, isHeadquartersUser, - isSupervisor, - currentUserId, }) => { const [isPageReload, setIsPageReload] = useState(true); useEffect(() => { @@ -99,7 +96,6 @@ const TableQueue = ({ queueResult: { totalCount = 0, data = [], - availableOfficeUsers = [], page = getTableQueuePageSessionStorageValue(sessionStorageKey) || defaultPage, perPage = getTableQueuePageSizeSessionStorageValue(sessionStorageKey) || defaultPageSize, }, @@ -123,13 +119,6 @@ const TableQueue = ({ [], ); const tableData = useMemo(() => data, [data]); - const formattedAvailableOfficeUsers = formatAvailableOfficeUsers(availableOfficeUsers, isSupervisor, currentUserId); - // attach the available office users to the moves/row - const tableDataWithAvailableUsers = tableData?.map((ele) => { - const newEle = { ...ele }; - newEle.availableOfficeUsers = formattedAvailableOfficeUsers; - return newEle; - }); const tableColumns = useMemo(() => columns, [columns]); const { @@ -150,7 +139,7 @@ const TableQueue = ({ } = useTable( { columns: tableColumns, - data: tableDataWithAvailableUsers, + data: tableData, initialState: { hiddenColumns: defaultHiddenColumns, pageSize: perPage, diff --git a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx index f7a4fdbcad2..f0e36adf3fa 100644 --- a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx +++ b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx @@ -48,9 +48,15 @@ import ConnectedFlashMessage from 'containers/FlashMessage/FlashMessage'; import { isNullUndefinedOrWhitespace } from 'shared/utils'; import CustomerSearchForm from 'components/CustomerSearchForm/CustomerSearchForm'; import MultiSelectTypeAheadCheckBoxFilter from 'components/Table/Filters/MutliSelectTypeAheadCheckboxFilter'; -import { formatAvailableOfficeUsersForRow } from 'utils/queues'; +import { formatAvailableOfficeUsersForRow, handleQueueAssignment } from 'utils/queues'; -export const counselingColumns = (moveLockFlag, originLocationList, supervisor, isQueueManagementEnabled) => { +export const counselingColumns = ( + moveLockFlag, + originLocationList, + supervisor, + isQueueManagementEnabled, + currentUserId, +) => { const cols = [ createHeader( ' ', @@ -196,10 +202,18 @@ export const counselingColumns = (moveLockFlag, originLocationList, supervisor, createHeader( 'Assigned', (row) => { - const { formattedAvailableOfficeUsers, assignedToUser } = formatAvailableOfficeUsersForRow(row); + const { formattedAvailableOfficeUsers, assignedToUser } = formatAvailableOfficeUsersForRow( + row, + supervisor, + currentUserId, + ); return (
- + handleQueueAssignment(row.id, e.target.value, roleTypes.SERVICES_COUNSELOR)} + title="Assigned dropdown" + > {formattedAvailableOfficeUsers}
@@ -207,6 +221,7 @@ export const counselingColumns = (moveLockFlag, originLocationList, supervisor, }, { id: 'assignedTo', + isFilterable: true, }, ), ); @@ -364,7 +379,7 @@ export const closeoutColumns = (moveLockFlag, ppmCloseoutGBLOC, ppmCloseoutOrigi }), ]; -const ServicesCounselingQueue = ({ userPrivileges, currentUserId }) => { +const ServicesCounselingQueue = ({ userPrivileges, currentUserId, isQueueManagementFFEnabled }) => { const { queueType } = useParams(); const { data, isLoading, isError } = useUserQueries(); @@ -372,7 +387,6 @@ const ServicesCounselingQueue = ({ userPrivileges, currentUserId }) => { const [isCounselorMoveCreateFFEnabled, setisCounselorMoveCreateFFEnabled] = useState(false); const [moveLockFlag, setMoveLockFlag] = useState(false); - const [isQueueManagementEnabled, setIsQueueManagementEnabled] = useState(false); const [setErrorState] = useState({ hasError: false, error: undefined, info: undefined }); const [originLocationList, setOriginLocationList] = useState([]); const [ppmCloseoutOriginLocationList, setPpmCloseoutOriginLocationList] = useState([]); @@ -403,8 +417,6 @@ const ServicesCounselingQueue = ({ userPrivileges, currentUserId }) => { setisCounselorMoveCreateFFEnabled(isEnabled); const lockedMoveFlag = await isBooleanFlagEnabled('move_lock'); setMoveLockFlag(lockedMoveFlag); - const assignedColFlag = await isBooleanFlagEnabled('queue_management'); - setIsQueueManagementEnabled(assignedColFlag); } catch (error) { const { message } = error; milmoveLogger.error({ message, info: null }); @@ -607,7 +619,13 @@ const ServicesCounselingQueue = ({ userPrivileges, currentUserId }) => { defaultSortedColumns={[{ id: 'submittedAt', desc: false }]} disableMultiSort disableSortBy={false} - columns={counselingColumns(moveLockFlag, originLocationList, supervisor, isQueueManagementEnabled)} + columns={counselingColumns( + moveLockFlag, + originLocationList, + supervisor, + isQueueManagementFFEnabled, + currentUserId, + )} title="Moves" handleClick={handleClick} useQueries={useServicesCounselingQueueQueries} diff --git a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.test.jsx b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.test.jsx index cc643ed75ba..002e4fe78db 100644 --- a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.test.jsx +++ b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.test.jsx @@ -105,6 +105,23 @@ const needsCounselingMoves = { name: 'Area 51', }, originGBLOC: 'LKNQ', + assignedTo: { + officeUserId: 'exampleId1', + firstName: 'Jimmy', + lastName: 'John', + }, + availableOfficeUsers: [ + { + officeUserId: 'exampleId1', + firstName: 'Jimmy', + lastName: 'John', + }, + { + officeUserId: 'exampleId2', + firstName: 'John', + lastName: 'Denver', + }, + ], }, { id: 'move2', @@ -124,6 +141,23 @@ const needsCounselingMoves = { }, originGBLOC: 'LKNQ', counselingOffice: '', + assignedTo: { + officeUserId: 'exampleId2', + firstName: 'John', + lastName: 'Denver', + }, + availableOfficeUsers: [ + { + officeUserId: 'exampleId1', + firstName: 'Jimmy', + lastName: 'John', + }, + { + officeUserId: 'exampleId2', + firstName: 'John', + lastName: 'Denver', + }, + ], }, { id: 'move3', @@ -141,6 +175,23 @@ const needsCounselingMoves = { name: 'Denver, 80136', }, originGBLOC: 'LKNQ', + assignedTo: { + officeUserId: 'exampleId1', + firstName: 'Jimmy', + lastName: 'John', + }, + availableOfficeUsers: [ + { + officeUserId: 'exampleId1', + firstName: 'Jimmy', + lastName: 'John', + }, + { + officeUserId: 'exampleId2', + firstName: 'John', + lastName: 'Denver', + }, + ], }, ], }, @@ -168,6 +219,11 @@ const serviceCounselingCompletedMoves = { name: 'Area 51', }, originGBLOC: 'LKNQ', + assignedTo: { + id: 'exampleId1', + firstname: 'Jimmy', + lastname: 'John', + }, }, { id: 'move2', @@ -186,6 +242,11 @@ const serviceCounselingCompletedMoves = { }, originGBLOC: 'LKNQ', counselingOffice: '67592323-fc7e-4b35-83a7-57faa53b7acf', + assignedTo: { + id: 'exampleId1', + firstname: 'Jimmy', + lastname: 'John', + }, }, ], }, @@ -201,7 +262,7 @@ describe('ServicesCounselingQueue', () => { useServicesCounselingQueueQueries.mockReturnValue(emptyServiceCounselingMoves); const wrapper = mount( - + , ); @@ -221,12 +282,17 @@ describe('ServicesCounselingQueue', () => { describe('Service Counselor', () => { useUserQueries.mockReturnValue(serviceCounselorUser); useServicesCounselingQueueQueries.mockReturnValue(needsCounselingMoves); + isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true)); const wrapper = mount( - + + , + ); + render( + + , ); - it('displays move header with needs service counseling count', () => { expect(wrapper.find('h1').text()).toBe('Moves (3)'); }); @@ -251,6 +317,7 @@ describe('ServicesCounselingQueue', () => { expect(firstMove.find('td.branch').text()).toBe('Army'); expect(firstMove.find('td.originGBLOC').text()).toBe('LKNQ'); expect(firstMove.find('td.originDutyLocation').text()).toBe('Area 51'); + expect(firstMove.find('td.assignedTo').text()).toBe('John, Jimmy'); const secondMove = moves.at(1); expect(secondMove.find('td.lastName').text()).toBe('test another last, test another first'); @@ -263,6 +330,7 @@ describe('ServicesCounselingQueue', () => { expect(secondMove.find('td.branch').text()).toBe('Coast Guard'); expect(secondMove.find('td.originGBLOC').text()).toBe('LKNQ'); expect(secondMove.find('td.originDutyLocation').text()).toBe('Los Alamos'); + expect(secondMove.find('td.assignedTo').text()).toBe('Denver, John'); const thirdMove = moves.at(2); expect(thirdMove.find('td.lastName').text()).toBe('test third last, test third first'); @@ -274,6 +342,7 @@ describe('ServicesCounselingQueue', () => { expect(thirdMove.find('td.branch').text()).toBe('Marine Corps'); expect(thirdMove.find('td.originGBLOC').text()).toBe('LKNQ'); expect(thirdMove.find('td.originDutyLocation').text()).toBe('Denver, 80136'); + expect(thirdMove.find('td.assignedTo').text()).toBe('John, Jimmy'); }); it('sorts by submitted at date ascending by default', () => { @@ -293,6 +362,7 @@ describe('ServicesCounselingQueue', () => { expect(wrapper.find('th[data-testid="originDutyLocation"][role="columnheader"]').prop('onClick')).not.toBe( undefined, ); + expect(wrapper.find('th[data-testid="assignedTo"][role="columnheader"]').prop('onClick')).not.toBe(undefined); }); it('disables sort by for origin GBLOC and status columns', () => { @@ -409,7 +479,7 @@ describe('ServicesCounselingQueue', () => { useServicesCounselingQueuePPMQueries.mockReturnValue(emptyServiceCounselingMoves); render( - + , ); diff --git a/src/pages/Office/index.jsx b/src/pages/Office/index.jsx index b8a65c146fc..6dfbe8409f0 100644 --- a/src/pages/Office/index.jsx +++ b/src/pages/Office/index.jsx @@ -112,6 +112,7 @@ export class OfficeApp extends Component { oktaNeedsLoggedOut: undefined, hqRoleFlag: !!props.hqRoleFlag, gsrRoleFlag: undefined, + queueManagementFlag: undefined, }; } @@ -152,6 +153,10 @@ export class OfficeApp extends Component { this.setState({ gsrRoleFlag: gsrRoleFlagValue, }); + const isQueueManagementFlagValue = await isBooleanFlagEnabled('queue_management'); + this.setState({ + queueManagementFlag: isQueueManagementFlagValue, + }); } catch (error) { retryPageLoading(error); } @@ -171,7 +176,8 @@ export class OfficeApp extends Component { } render() { - const { hasError, error, info, oktaLoggedOut, oktaNeedsLoggedOut, hqRoleFlag, gsrRoleFlag } = this.state; + const { hasError, error, info, oktaLoggedOut, oktaNeedsLoggedOut, hqRoleFlag, gsrRoleFlag, queueManagementFlag } = + this.state; const { activeRole, officeUserId, @@ -307,7 +313,11 @@ export class OfficeApp extends Component { end element={ - + } /> diff --git a/src/services/ghcApi.js b/src/services/ghcApi.js index 29f1d4aba92..f3476b7c253 100644 --- a/src/services/ghcApi.js +++ b/src/services/ghcApi.js @@ -844,20 +844,6 @@ export async function patchPPMSIT({ ppmShipmentId, payload, eTag }) { ); } -export async function updateAssignedOfficeUserForMove({ moveID, officeUserId, roleType }) { - return makeGHCRequest('move.updateAssignedOfficeUser', { - moveID, - body: { officeUserId, roleType }, - }); -} - -export async function deleteAssignedOfficeUserForMove({ moveID, roleType }) { - return makeGHCRequest('move.deleteAssignedOfficeUser', { - moveID, - body: { roleType }, - }); -} - export async function bulkDownloadPaymentRequest(paymentRequestID) { return makeGHCRequestRaw('paymentRequests.bulkDownload', { paymentRequestID }); } @@ -872,3 +858,17 @@ export async function dateSelectionIsWeekendHoliday(countryCode, date) { { normalize: false }, ); } + +export async function updateAssignedOfficeUserForMove({ moveID, officeUserId, roleType }) { + return makeGHCRequest('move.updateAssignedOfficeUser', { + moveID, + body: { officeUserId, roleType }, + }); +} + +export async function deleteAssignedOfficeUserForMove({ moveID, roleType }) { + return makeGHCRequest('move.deleteAssignedOfficeUser', { + moveID, + body: { roleType }, + }); +} diff --git a/src/utils/queues.jsx b/src/utils/queues.jsx index d6503be6e66..c50ae1920d3 100644 --- a/src/utils/queues.jsx +++ b/src/utils/queues.jsx @@ -1,24 +1,21 @@ import React from 'react'; +import { deleteAssignedOfficeUserForMove, updateAssignedOfficeUserForMove } from 'services/ghcApi'; import { DEFAULT_EMPTY_VALUE } from 'shared/constants'; -const addAssignedOfficeUser = (users, assignedTo) => { - const newAvailableOfficeUsers = users.slice(); - const { lastName, firstName, id } = assignedTo; - newAvailableOfficeUsers.push({ - label: `${lastName}, ${firstName}`, - value: id, - }); - return newAvailableOfficeUsers; -}; - export const formatOfficeUser = (user) => { const fullName = `${user?.lastName}, ${user?.firstName}`; return { label: fullName, value: user.officeUserId }; }; +const addAssignedOfficeUser = (users, assignedTo) => { + const newAvailableOfficeUsers = users.slice(); + newAvailableOfficeUsers.push(formatOfficeUser(assignedTo)); + return newAvailableOfficeUsers; +}; + export const formatAvailableOfficeUsers = (users, isSupervisor, currentUserId) => { - if (!users.length || isSupervisor === undefined || currentUserId === undefined) return []; + if (!users?.length || isSupervisor === undefined || currentUserId === undefined) return []; // instantiate array with empty value for unassign purposes down the road const newAvailableOfficeUsers = [{ label: DEFAULT_EMPTY_VALUE, value: null }]; @@ -40,19 +37,23 @@ export const formatAvailableOfficeUsers = (users, isSupervisor, currentUserId) = return newAvailableOfficeUsers; }; -export const formatAvailableOfficeUsersForRow = (row) => { +export const formatAvailableOfficeUsersForRow = (originalRow, supervisor, currentUserId) => { // dupe the row to avoid issues with passing office user array by reference - const updatedRow = { ...row }; + const row = { ...originalRow }; + row.availableOfficeUsers = formatAvailableOfficeUsers(row.availableOfficeUsers, supervisor, currentUserId); // if the move is assigned to a user not present in availableOfficeUsers // lets push them onto the end - if (row.assignedTo !== undefined && !row.availableOfficeUsers?.some((user) => user.value === row.assignedTo.id)) { - updatedRow.availableOfficeUsers = addAssignedOfficeUser(row.availableOfficeUsers, row.assignedTo); + if ( + row.assignedTo !== undefined && + !row.availableOfficeUsers?.some((user) => user.value === row.assignedTo.officeUserId) + ) { + row.availableOfficeUsers = addAssignedOfficeUser(row.availableOfficeUsers, row.assignedTo); } - const { assignedTo, availableOfficeUsers } = updatedRow; + const { assignedTo, availableOfficeUsers } = row; // if there is an assigned user, assign to a variable so we can set a default value below - const assignedToUser = availableOfficeUsers.find((user) => user.value === assignedTo?.id); + const assignedToUser = availableOfficeUsers.find((user) => user.value === assignedTo?.officeUserId); const formattedAvailableOfficeUsers = availableOfficeUsers.map(({ value, label }) => (