Skip to content

Commit

Permalink
B 21445 INT too bulk data (#14494)
Browse files Browse the repository at this point in the history
* added TOO query and handler for bulk management:

* fixed query to meet hidden AC
  • Loading branch information
loganwc authored Jan 8, 2025
1 parent 7f0b037 commit 3980551
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 0 deletions.
21 changes: 21 additions & 0 deletions pkg/handlers/ghcapi/queues.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,27 @@ func (h GetBulkAssignmentDataHandler) Handle(
return queues.NewGetBulkAssignmentDataInternalServerError(), err
}

officeUserData = payloads.BulkAssignmentData(appCtx, moves, officeUsers, officeUser.TransportationOffice.ID)
case string(models.QueueTypeTaskOrder):
// fetch the TOOs who work at their office
officeUsers, err := h.OfficeUserFetcherPop.FetchOfficeUsersWithWorkloadByRoleAndOffice(
appCtx,
roles.RoleTypeTOO,
officeUser.TransportationOfficeID,
)
if err != nil {
appCtx.Logger().Error("Error retreiving office users", zap.Error(err))
return queues.NewGetBulkAssignmentDataInternalServerError(), err
}
// fetch the moves available to be assigned to their office users
moves, err := h.MoveFetcherBulkAssignment.FetchMovesForBulkAssignmentTaskOrder(
appCtx, officeUser.TransportationOffice.Gbloc, officeUser.TransportationOffice.ID,
)
if err != nil {
appCtx.Logger().Error("Error retreiving moves", zap.Error(err))
return queues.NewGetBulkAssignmentDataInternalServerError(), err
}

officeUserData = payloads.BulkAssignmentData(appCtx, moves, officeUsers, officeUser.TransportationOffice.ID)
}
return queues.NewGetBulkAssignmentDataOK().WithPayload(&officeUserData), nil
Expand Down
65 changes: 65 additions & 0 deletions pkg/handlers/ghcapi/queues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1884,4 +1884,69 @@ func (suite *HandlerSuite) TestGetBulkAssignmentDataHandler() {
suite.Len(payload.AvailableOfficeUsers, 1)
suite.Len(payload.BulkAssignmentMoveIDs, 1)
})
suite.Run("TOO: returns properly formatted bulk assignment data", func() {
transportationOffice := factory.BuildTransportationOffice(suite.DB(), nil, nil)

officeUser := factory.BuildOfficeUserWithPrivileges(suite.DB(), []factory.Customization{
{
Model: models.OfficeUser{
Email: "[email protected]",
Active: true,
},
},
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CounselingOffice,
},
{
Model: models.User{
Privileges: []models.Privilege{
{
PrivilegeType: models.PrivilegeTypeSupervisor,
},
},
Roles: []roles.Role{
{
RoleType: roles.RoleTypeTOO,
},
},
},
},
}, nil)

// move to appear in the return
factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Status: models.MoveStatusAPPROVALSREQUESTED,
},
},
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CounselingOffice,
},
}, nil)

request := httptest.NewRequest("GET", "/queues/bulk-assignment", nil)
request = suite.AuthenticateOfficeRequest(request, officeUser)
params := queues.GetBulkAssignmentDataParams{
HTTPRequest: request,
QueueType: models.StringPointer("TASK_ORDER"),
}
handlerConfig := suite.HandlerConfig()
handler := GetBulkAssignmentDataHandler{
handlerConfig,
officeusercreator.NewOfficeUserFetcherPop(),
movefetcher.NewMoveFetcherBulkAssignment(),
}
response := handler.Handle(params)
suite.IsNotErrResponse(response)
suite.IsType(&queues.GetBulkAssignmentDataOK{}, response)
payload := response.(*queues.GetBulkAssignmentDataOK).Payload
suite.NoError(payload.Validate(strfmt.Default))
suite.Len(payload.AvailableOfficeUsers, 1)
suite.Len(payload.BulkAssignmentMoveIDs, 1)
})
}
1 change: 1 addition & 0 deletions pkg/services/move.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type MoveFetcher interface {

type MoveFetcherBulkAssignment interface {
FetchMovesForBulkAssignmentCounseling(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error)
FetchMovesForBulkAssignmentTaskOrder(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error)
}

//go:generate mockery --name MoveSearcher
Expand Down
47 changes: 47 additions & 0 deletions pkg/services/move/move_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,50 @@ func (f moveFetcherBulkAssignment) FetchMovesForBulkAssignmentCounseling(appCtx

return moves, nil
}

func (f moveFetcherBulkAssignment) FetchMovesForBulkAssignmentTaskOrder(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error) {
var moves []models.MoveWithEarliestDate

err := appCtx.DB().
RawQuery(`SELECT
moves.id,
MIN(LEAST(
COALESCE(mto_shipments.requested_pickup_date, '9999-12-31'),
COALESCE(mto_shipments.requested_delivery_date, '9999-12-31'),
COALESCE(ppm_shipments.expected_departure_date, '9999-12-31')
)) AS earliest_date
FROM moves
INNER JOIN orders ON orders.id = moves.orders_id
INNER JOIN service_members ON orders.service_member_id = service_members.id
INNER JOIN mto_shipments ON mto_shipments.move_id = moves.id
LEFT JOIN ppm_shipments ON ppm_shipments.shipment_id = mto_shipments.id
LEFT JOIN move_to_gbloc ON move_to_gbloc.move_id = moves.id
WHERE
(moves.status IN ('APPROVALS REQUESTED', 'SUBMITTED', 'SERVICE COUNSELING COMPLETED'))
AND moves.show = $1
AND moves.too_assigned_id IS NULL
AND (orders.orders_type NOT IN ($2, $3, $4))
AND service_members.affiliation != 'MARINES'
AND ((mto_shipments.shipment_type != $5 AND move_to_gbloc.gbloc = $6) OR (mto_shipments.shipment_type = $7 AND orders.gbloc = $8))
GROUP BY moves.id
ORDER BY earliest_date ASC`,
models.BoolPointer(true),
internalmessages.OrdersTypeBLUEBARK,
internalmessages.OrdersTypeWOUNDEDWARRIOR,
internalmessages.OrdersTypeSAFETY,
models.MTOShipmentTypeHHGOutOfNTSDom,
gbloc,
models.MTOShipmentTypeHHGOutOfNTSDom,
gbloc).
All(&moves)

if err != nil {
return nil, fmt.Errorf("error fetching moves for office: %s with error %w", officeId, err)
}

if len(moves) < 1 {
return nil, nil
}

return moves, nil
}
61 changes: 61 additions & 0 deletions pkg/services/move/move_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,65 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() {
// Orders type isn't WW, BB, or Safety
suite.Equal(assignedMove.Orders.OrdersType, internalmessages.OrdersTypePERMANENTCHANGEOFSTATION)
})

suite.Run("TOO: Returns moves that fulfill the query criteria", func() {
moveFetcher := NewMoveFetcherBulkAssignment()
transportationOffice := factory.BuildTransportationOffice(suite.DB(), nil, nil)
officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CounselingOffice,
},
}, []roles.RoleType{roles.RoleTypeTOO})

factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Status: models.MoveStatusAPPROVALSREQUESTED,
},
},
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CounselingOffice,
},
}, nil)

factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Status: models.MoveStatusServiceCounselingCompleted,
},
},
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CounselingOffice,
},
}, nil)

marine := models.AffiliationMARINES
factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Status: models.MoveStatusServiceCounselingCompleted,
},
},
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CounselingOffice,
},
{
Model: models.ServiceMember{
Affiliation: &marine,
},
},
}, nil)

moves, err := moveFetcher.FetchMovesForBulkAssignmentTaskOrder(suite.AppContextForTest(), "KKFA", officeUser.TransportationOffice.ID)
suite.FatalNoError(err)
suite.Equal(2, len(moves))
})
}

0 comments on commit 3980551

Please sign in to comment.