Skip to content

Commit

Permalink
Merge pull request #14539 from transcom/B-22129-Closeout-Data
Browse files Browse the repository at this point in the history
B 22129 closeout data
  • Loading branch information
pambecker authored Jan 31, 2025
2 parents 63ebb93 + f7ca0f0 commit 089d0a2
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 8 deletions.
6 changes: 4 additions & 2 deletions pkg/gen/ghcapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/gen/ghcmessages/available_office_user.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions pkg/handlers/ghcapi/queues.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,27 @@ func (h GetBulkAssignmentDataHandler) Handle(
return queues.NewGetBulkAssignmentDataInternalServerError(), err
}

officeUserData = payloads.BulkAssignmentData(appCtx, moves, officeUsers, officeUser.TransportationOffice.ID)
case string(models.QueueTypeCloseout):
// fetch the Services Counselors who work at their office
officeUsers, err := h.OfficeUserFetcherPop.FetchOfficeUsersWithWorkloadByRoleAndOffice(
appCtx,
roles.RoleTypeServicesCounselor,
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.FetchMovesForBulkAssignmentCloseout(
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)
case string(models.QueueTypeTaskOrder):
// fetch the TOOs who work at their office
Expand Down
74 changes: 73 additions & 1 deletion pkg/handlers/ghcapi/queues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1754,7 +1754,6 @@ 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)

Expand Down Expand Up @@ -1820,4 +1819,77 @@ func (suite *HandlerSuite) TestGetBulkAssignmentDataHandler() {
suite.Len(payload.AvailableOfficeUsers, 1)
suite.Len(payload.BulkAssignmentMoveIDs, 1)
})
suite.Run("returns properly formatted closeout 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.RoleTypeServicesCounselor,
},
},
},
},
}, nil)

submittedAt := time.Now()

// move to appear in the return
factory.BuildMoveWithPPMShipment(suite.DB(), []factory.Customization{
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CloseoutOffice,
},
{
Model: models.PPMShipment{
Status: models.PPMShipmentStatusNeedsCloseout,
SubmittedAt: &submittedAt,
},
},
{
Model: models.Move{
Status: models.MoveStatusAPPROVED,
},
},
}, nil)

request := httptest.NewRequest("GET", "/queues/bulk-assignment", nil)
request = suite.AuthenticateOfficeRequest(request, officeUser)
params := queues.GetBulkAssignmentDataParams{
HTTPRequest: request,
QueueType: models.StringPointer("CLOSEOUT"),
}
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)
FetchMovesForBulkAssignmentCloseout(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error)
FetchMovesForBulkAssignmentTaskOrder(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error)
}

Expand Down
54 changes: 54 additions & 0 deletions pkg/services/move/move_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,60 @@ func (f moveFetcherBulkAssignment) FetchMovesForBulkAssignmentCounseling(appCtx
return moves, nil
}

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

query := `SELECT
moves.id,
ppm_shipments.submitted_at AS earliest_date
FROM moves
INNER JOIN orders ON orders.id = moves.orders_id
INNER JOIN service_members ON service_members.id = orders.service_member_id
INNER JOIN mto_shipments ON mto_shipments.move_id = moves.id
INNER JOIN ppm_shipments ON ppm_shipments.shipment_id = mto_shipments.id
WHERE
(moves.status IN ('APPROVED', 'SERVICE COUNSELING COMPLETED'))
AND moves.show = $1
AND moves.sc_assigned_id IS NULL`

switch gbloc {
case "NAVY":
query += ` AND (service_members.affiliation in ('` + string(models.AffiliationNAVY) + `'))`
case "TVCB":
query += ` AND (service_members.affiliation in ('` + string(models.AffiliationMARINES) + `'))`
case "USCG":
query += ` AND (service_members.affiliation in ('` + string(models.AffiliationCOASTGUARD) + `'))`
default:
query += ` AND moves.closeout_office_id = '` + officeId.String() + `'
AND (service_members.affiliation NOT IN ('` +
string(models.AffiliationNAVY) + `', '` +
string(models.AffiliationMARINES) + `', '` +
string(models.AffiliationCOASTGUARD) + `'))`
}

query += ` AND (ppm_shipments.status IN ($2))
AND (orders.orders_type NOT IN ($3, $4, $5))
GROUP BY moves.id, ppm_shipments.submitted_at
ORDER BY earliest_date ASC`

err := appCtx.DB().RawQuery(query,
models.BoolPointer(true),
models.PPMShipmentStatusNeedsCloseout,
internalmessages.OrdersTypeBLUEBARK,
internalmessages.OrdersTypeWOUNDEDWARRIOR,
internalmessages.OrdersTypeSAFETY).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
}

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

Expand Down
88 changes: 84 additions & 4 deletions pkg/services/move/move_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,90 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() {
suite.Equal(assignedMove.Orders.OrdersType, internalmessages.OrdersTypePERMANENTCHANGEOFSTATION)
})

suite.Run("Closeout returns non Navy/USCG/USMC ppms in needs closeout status", func() {
moveFetcher := NewMoveFetcherBulkAssignment()
transportationOffice := factory.BuildTransportationOffice(suite.DB(), nil, nil)
officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CloseoutOffice,
},
}, []roles.RoleType{roles.RoleTypeServicesCounselor})

submittedAt := time.Now()

// create non USMC/USCG/NAVY ppm in need closeout status
factory.BuildMoveWithPPMShipment(suite.DB(), []factory.Customization{
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CloseoutOffice,
},
{
Model: models.PPMShipment{
Status: models.PPMShipmentStatusNeedsCloseout,
SubmittedAt: &submittedAt,
},
},
{
Model: models.Move{
Status: models.MoveStatusAPPROVED,
},
},
}, nil)

// create non closeout needed ppm
factory.BuildMoveWithPPMShipment(suite.DB(), []factory.Customization{
{
Model: transportationOffice,
LinkOnly: true,
Type: &factory.TransportationOffices.CloseoutOffice,
},
{
Model: models.PPMShipment{
Status: models.PPMShipmentStatusWaitingOnCustomer,
SubmittedAt: &submittedAt,
},
},
{
Model: models.Move{
Status: models.MoveStatusAPPROVED,
},
},
}, nil)

marine := models.AffiliationMARINES
marinePPM := factory.BuildPPMShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Status: models.MoveStatusAPPROVED,
},
},
{
Model: models.MTOShipment{
ShipmentType: models.MTOShipmentTypePPM,
},
},
{
Model: models.PPMShipment{
Status: models.PPMShipmentStatusNeedsCloseout,
SubmittedAt: &submittedAt,
},
},
{
Model: models.ServiceMember{
Affiliation: &marine,
},
},
}, nil)

moves, err := moveFetcher.FetchMovesForBulkAssignmentCloseout(suite.AppContextForTest(), "KKFA", officeUser.TransportationOffice.ID)
suite.FatalNoError(err)
suite.Equal(1, len(moves))
suite.NotEqual(marinePPM.ID, moves[0].ID)
})

suite.Run("TOO: Returns moves that fulfill the query criteria", func() {
moveFetcher := NewMoveFetcherBulkAssignment()
transportationOffice := factory.BuildTransportationOffice(suite.DB(), nil, nil)
Expand All @@ -444,7 +528,6 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() {
Type: &factory.TransportationOffices.CounselingOffice,
},
}, []roles.RoleType{roles.RoleTypeTOO})

factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Expand All @@ -457,7 +540,6 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() {
Type: &factory.TransportationOffices.CounselingOffice,
},
}, nil)

factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Model: models.Move{
Expand All @@ -470,7 +552,6 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() {
Type: &factory.TransportationOffices.CounselingOffice,
},
}, nil)

marine := models.AffiliationMARINES
factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{
{
Expand All @@ -489,7 +570,6 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() {
},
},
}, nil)

moves, err := moveFetcher.FetchMovesForBulkAssignmentTaskOrder(suite.AppContextForTest(), "KKFA", officeUser.TransportationOffice.ID)
suite.FatalNoError(err)
suite.Equal(2, len(moves))
Expand Down
1 change: 1 addition & 0 deletions swagger-def/ghc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7091,6 +7091,7 @@ definitions:
type: boolean
workload:
type: integer
x-omitempty: false
BulkAssignmentData:
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions swagger/ghc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7440,6 +7440,7 @@ definitions:
type: boolean
workload:
type: integer
x-omitempty: false
BulkAssignmentData:
type: object
properties:
Expand Down

0 comments on commit 089d0a2

Please sign in to comment.