From 59b28212204edb53eddc02c2164d520b2a9cf380 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 23 Dec 2024 19:45:59 +0000 Subject: [PATCH 01/26] easier to read changes --- pkg/services/order/order_fetcher.go | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 923a4dfe82b..1001841c235 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -122,8 +122,9 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid tooAssignedUserQuery := tooAssignedUserFilter(params.TOOAssignedUser) sortOrderQuery := sortOrder(params.Sort, params.Order, ppmCloseoutGblocs) counselingQuery := counselingOfficeFilter(params.CounselingOffice) + tooDestinationRequestsQuery := tooDestinationOnlyRequestsFilter(role) // Adding to an array so we can iterate over them and apply the filters after the query structure is set below - options := [20]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery} + options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, tooDestinationRequestsQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery} var query *pop.Query if ppmCloseoutGblocs { @@ -191,6 +192,9 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid } if role == roles.RoleTypeTOO { query.LeftJoin("office_users as assigned_user", "moves.too_assigned_id = assigned_user.id") + query.LeftJoin("mto_service_items", "mto_shipments.id = mto_service_items.mto_shipment_id"). + LeftJoin("re_services", "mto_service_items.re_service_id = re_services.id"). + LeftJoin("shipment_address_updates", "shipment_address_updates.shipment_id = mto_shipments.id AND shipment_address_updates.new_address_id != mto_shipments.destination_address_id") } if params.NeedsPPMCloseout != nil { @@ -781,3 +785,26 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption } } } + +func tooDestinationOnlyRequestsFilter(role roles.RoleType) QueryOption { + return func(query *pop.Query) { + if role == roles.RoleTypeTOO { + query.Where(` + ( + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code NOT IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT'))) + AND (moves.status = 'SUBMITTED' OR moves.status = 'SERVICE COUNSELING COMPLETED' OR moves.status = 'APPROVALS REQUESTED') + ) + `) + // OR --excess weight + // ( + // (moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) + // AND (moves.status = 'SUBMITTED' OR moves.status = 'SERVICE COUNSELING COMPLETED' OR moves.status = 'APPROVALS REQUESTED') + // ) + // OR --excess ub weight + // ( + // (moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL) + // AND (moves.status = 'SUBMITTED' OR moves.status = 'SERVICE COUNSELING COMPLETED' OR moves.status = 'APPROVALS REQUESTED') + // ) + } + } +} From e6a361bcfbc242023bc9cf268b4f927ff0be9ff4 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 23 Dec 2024 21:08:28 +0000 Subject: [PATCH 02/26] removing moves.status query --- pkg/services/order/order_fetcher.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 1001841c235..d89c510983e 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -791,10 +791,10 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType) QueryOption { if role == roles.RoleTypeTOO { query.Where(` ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code NOT IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT'))) - AND (moves.status = 'SUBMITTED' OR moves.status = 'SERVICE COUNSELING COMPLETED' OR moves.status = 'APPROVALS REQUESTED') + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code NOT IN ('DOFSIT', 'DOASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT'))) ) `) + // `) // OR --excess weight // ( // (moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) From 2f00fd42aad40495576f80fd730d5161c896f22f Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 23 Dec 2024 21:15:55 +0000 Subject: [PATCH 03/26] removing moves.status query --- pkg/services/order/order_fetcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index d89c510983e..399da9e61eb 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -124,7 +124,7 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid counselingQuery := counselingOfficeFilter(params.CounselingOffice) tooDestinationRequestsQuery := tooDestinationOnlyRequestsFilter(role) // Adding to an array so we can iterate over them and apply the filters after the query structure is set below - options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, tooDestinationRequestsQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery} + options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, tooDestinationRequestsQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery} var query *pop.Query if ppmCloseoutGblocs { From 4a570403c0b9a847408fdcf5bc74743846fe1d3c Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Tue, 24 Dec 2024 00:35:23 +0000 Subject: [PATCH 04/26] FINALLY --- pkg/services/order/order_fetcher.go | 30 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 399da9e61eb..59b582ccb26 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -122,9 +122,9 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid tooAssignedUserQuery := tooAssignedUserFilter(params.TOOAssignedUser) sortOrderQuery := sortOrder(params.Sort, params.Order, ppmCloseoutGblocs) counselingQuery := counselingOfficeFilter(params.CounselingOffice) - tooDestinationRequestsQuery := tooDestinationOnlyRequestsFilter(role) + tooDestinationRequestsQuery := tooDestinationOnlyRequestsFilter(role, params.Locator) // Adding to an array so we can iterate over them and apply the filters after the query structure is set below - options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, tooDestinationRequestsQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery} + options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery, tooDestinationRequestsQuery} var query *pop.Query if ppmCloseoutGblocs { @@ -786,25 +786,23 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption } } -func tooDestinationOnlyRequestsFilter(role roles.RoleType) QueryOption { +func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) QueryOption { return func(query *pop.Query) { if role == roles.RoleTypeTOO { - query.Where(` + if locator != nil { + // ignore this query if searching for a move + query.Where("moves.locator = ?", strings.ToUpper(*locator)) + } else { + query.Where(` + ( + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT'))) + ) + OR ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code NOT IN ('DOFSIT', 'DOASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT'))) + ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') ) `) - // `) - // OR --excess weight - // ( - // (moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) - // AND (moves.status = 'SUBMITTED' OR moves.status = 'SERVICE COUNSELING COMPLETED' OR moves.status = 'APPROVALS REQUESTED') - // ) - // OR --excess ub weight - // ( - // (moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL) - // AND (moves.status = 'SUBMITTED' OR moves.status = 'SERVICE COUNSELING COMPLETED' OR moves.status = 'APPROVALS REQUESTED') - // ) + } } } } From d65894e6eaa77960875c754d7d0ae931441d7b8c Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Tue, 24 Dec 2024 02:48:19 +0000 Subject: [PATCH 05/26] test updates --- pkg/services/order/order_fetcher_test.go | 148 +++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index 57e85401246..b19d968a162 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -580,6 +580,154 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, len(moves)) suite.Equal(createdPPM.Shipment.MoveTaskOrder.Locator, moves[0].Locator) }) + + suite.Run("task order queue does not return move with ONLY a destination address update request", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + // build a move with a destination address request, should NOT appear in Task Order Queue + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + testUUID := uuid.UUID{} + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + DestinationAddressID: &testUUID, + }, + }, + }, nil) + + suite.NotNil(shipment) + // newTestUUID := uuid.UUID{} + + shipmentAddressUpdate := factory.BuildShipmentAddressUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: models.ShipmentAddressUpdate{ + NewAddressID: testUUID, + }, + }, + }, []factory.Trait{factory.GetTraitShipmentAddressUpdateRequested}) + suite.NotNil(shipmentAddressUpdate) + + // build a second move + move2 := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + Show: models.BoolPointer(true), + }, + }}, nil) + suite.NotNil(move2) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + // even though 2 moves were created, only one will be returned from the call to List Orders since we filter out + // the one with only a shipment address update to be routed to the destination requests queue + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + + suite.Run("task order queue does not return move with ONLY requested destination SIT service items", func() { + // officeUser, _, session := setupTestData() + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with a only origin service items + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + originSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOFSIT, + }, + }, + }, nil) + suite.NotNil(originSITServiceItem) + + // build a move with a both origin and destination service items + move2 := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + shipment2 := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move2, + LinkOnly: true, + }, + }, nil) + + destinationSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment2, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDDFSIT, + }, + }, + }, nil) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.Equal(models.MTOServiceItemStatusSubmitted, destinationSITServiceItem.Status) + + suite.FatalNoError(err) + // even though 2 moves were created, only one will be returned from the call to List Orders since we filter out + // the one with only destination service items + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) } func (suite *OrderServiceSuite) TestListOrderWithAssignedUserSingle() { // Under test: ListOrders From f572ddf60edb06e3ca0553fe2201e0ac5dae5659 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Tue, 24 Dec 2024 05:07:37 +0000 Subject: [PATCH 06/26] fix queue handler test --- pkg/handlers/ghcapi/queues_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/handlers/ghcapi/queues_test.go b/pkg/handlers/ghcapi/queues_test.go index 6a658d6c2aa..aa251e2627c 100644 --- a/pkg/handlers/ghcapi/queues_test.go +++ b/pkg/handlers/ghcapi/queues_test.go @@ -478,6 +478,11 @@ func (suite *HandlerSuite) TestGetMoveQueuesHandlerFilters() { Status: models.MTOServiceItemStatusSubmitted, }, }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOFSIT, + }, + }, }, nil) // Service Counseling Completed Move From 2749f62432d219e351022ba0fe6b034b78bbb598 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 26 Dec 2024 21:29:51 +0000 Subject: [PATCH 07/26] remove comments --- pkg/services/order/order_fetcher_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index b19d968a162..be5ebf9c471 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -613,7 +613,6 @@ func (suite *OrderServiceSuite) TestListOrders() { }, nil) suite.NotNil(shipment) - // newTestUUID := uuid.UUID{} shipmentAddressUpdate := factory.BuildShipmentAddressUpdate(suite.DB(), []factory.Customization{ { @@ -652,7 +651,6 @@ func (suite *OrderServiceSuite) TestListOrders() { }) suite.Run("task order queue does not return move with ONLY requested destination SIT service items", func() { - // officeUser, _, session := setupTestData() officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) session := auth.Session{ ApplicationName: auth.OfficeApp, From 2bbb3dc016c4900b8d0bfd490815dae4968a4fe7 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 26 Dec 2024 22:49:23 +0000 Subject: [PATCH 08/26] nicer formatting for AND --- pkg/services/order/order_fetcher.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 59b582ccb26..d44e450229b 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -790,8 +790,21 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer return func(query *pop.Query) { if role == roles.RoleTypeTOO { if locator != nil { - // ignore this query if searching for a move - query.Where("moves.locator = ?", strings.ToUpper(*locator)) + query.Where(` + ( + moves.locator = ? + ) + AND + ( + ( + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT'))) + ) + OR + ( + ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') + ) + ) + `, strings.ToUpper(*locator)) } else { query.Where(` ( From b2b9e7830f2e9033bf1a712716144ba6a742bb27 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 26 Dec 2024 22:52:00 +0000 Subject: [PATCH 09/26] add additional origin service item reservice codes --- pkg/services/order/order_fetcher.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index d44e450229b..935309f27c1 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -797,7 +797,7 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer AND ( ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT'))) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) OR ( @@ -808,7 +808,7 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer } else { query.Where(` ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT'))) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) OR ( From 37849ff053bb020e850e5a509a35c23598a31aee Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Fri, 3 Jan 2025 19:38:21 +0000 Subject: [PATCH 10/26] update test to use search --- playwright/tests/office/txo/tooFlows.spec.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/playwright/tests/office/txo/tooFlows.spec.js b/playwright/tests/office/txo/tooFlows.spec.js index dd85150f3fd..412076deb28 100644 --- a/playwright/tests/office/txo/tooFlows.spec.js +++ b/playwright/tests/office/txo/tooFlows.spec.js @@ -626,17 +626,10 @@ test.describe('TOO user', () => { await page.getByRole('button', { name: 'Select task_ordering_officer' }).click(); }); test('weight-based multiplier prioritizes billed weight', async ({ page }) => { - await page.getByRole('row', { name: 'Select...' }).getByTestId('locator').getByTestId('TextBoxFilter').click(); - await page - .getByRole('row', { name: 'Select...' }) - .getByTestId('locator') - .getByTestId('TextBoxFilter') - .fill(moveLoc); - await page - .getByRole('row', { name: 'Select...' }) - .getByTestId('locator') - .getByTestId('TextBoxFilter') - .press('Enter'); + await page.getByRole('link', { name: 'Search' }).click(); + await page.getByTestId('searchText').click(); + await page.getByTestId('searchText').fill(moveLoc); + await page.getByTestId('searchText').press('Enter'); await page.getByTestId('locator-0').click(); await page.getByRole('link', { name: 'Payment requests' }).click(); await page.getByRole('button', { name: 'Review shipment weights' }).click(); From bea2ee0cc121c5266076af0f1068a1140bc483c6 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Fri, 3 Jan 2025 20:58:13 +0000 Subject: [PATCH 11/26] include DOPSIT --- pkg/services/order/order_fetcher.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 935309f27c1..d2cd6004f97 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -797,7 +797,7 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer AND ( ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) OR ( @@ -808,7 +808,7 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer } else { query.Where(` ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) OR ( From 5d7b9df2af67fdb165687bda97aab3a08b554cf7 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Fri, 3 Jan 2025 21:37:01 +0000 Subject: [PATCH 12/26] refactor into base query plus additional loc query if needed --- pkg/services/order/order_fetcher.go | 33 ++++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index d2cd6004f97..47a8d21c58d 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -194,7 +194,8 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid query.LeftJoin("office_users as assigned_user", "moves.too_assigned_id = assigned_user.id") query.LeftJoin("mto_service_items", "mto_shipments.id = mto_service_items.mto_shipment_id"). LeftJoin("re_services", "mto_service_items.re_service_id = re_services.id"). - LeftJoin("shipment_address_updates", "shipment_address_updates.shipment_id = mto_shipments.id AND shipment_address_updates.new_address_id != mto_shipments.destination_address_id") + LeftJoin("shipment_address_updates", "shipment_address_updates.shipment_id = mto_shipments.id AND shipment_address_updates.new_address_id != mto_shipments.destination_address_id"). + LeftJoin("sit_extensions", "mto_shipments.id = sit_extensions.mto_shipment_id") } if params.NeedsPPMCloseout != nil { @@ -789,32 +790,24 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) QueryOption { return func(query *pop.Query) { if role == roles.RoleTypeTOO { - if locator != nil { - query.Where(` - ( - moves.locator = ? - ) - AND + baseQuery := ` ( - ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) - ) - OR - ( - ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') - ) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) - `, strings.ToUpper(*locator)) - } else { - query.Where(` + OR ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) + ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') ) OR ( - ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') + ((sit_extensions.mto_shipment_id IS NOT NULL) AND sit_extensions.status = 'PENDING') ) - `) + ` + if locator != nil { + query.Where(` + (moves.locator = ?) AND ( `+baseQuery+`)`, strings.ToUpper(*locator)) + } else { + query.Where(baseQuery) } } } From 4fe3bd63018083d78173988f55b6b6a3b0aac4a1 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Fri, 3 Jan 2025 21:43:34 +0000 Subject: [PATCH 13/26] whoops get back in there DOPSIT --- pkg/services/order/order_fetcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 47a8d21c58d..80a0e20a829 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -792,7 +792,7 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer if role == roles.RoleTypeTOO { baseQuery := ` ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) OR ( From e5c31b8af9d00dfcb09e4db74bed01248b5d3e82 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Fri, 3 Jan 2025 21:47:50 +0000 Subject: [PATCH 14/26] remove nonexistest reservice code --- pkg/services/order/order_fetcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 80a0e20a829..004a13ebab3 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -792,7 +792,7 @@ func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) Quer if role == roles.RoleTypeTOO { baseQuery := ` ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DODSIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) + (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) ) OR ( From 77e66f5bbc0b168e4a6343af840b1cee2ca06ee1 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 6 Jan 2025 15:34:02 +0000 Subject: [PATCH 15/26] update move status for test --- pkg/services/order/order_fetcher_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index be5ebf9c471..f2101d283ce 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -635,7 +635,7 @@ func (suite *OrderServiceSuite) TestListOrders() { move2 := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ - Status: models.MoveStatusAPPROVED, + Status: models.MoveStatusAPPROVALSREQUESTED, Show: models.BoolPointer(true), }, }}, nil) From 5e57d2b31268fdcb7a41ae9513cc75b9d1c1ecaf Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Tue, 7 Jan 2025 15:57:02 +0000 Subject: [PATCH 16/26] add comment and update function name --- pkg/services/order/order_fetcher.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 004a13ebab3..c0c54ce9524 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -122,7 +122,7 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid tooAssignedUserQuery := tooAssignedUserFilter(params.TOOAssignedUser) sortOrderQuery := sortOrder(params.Sort, params.Order, ppmCloseoutGblocs) counselingQuery := counselingOfficeFilter(params.CounselingOffice) - tooDestinationRequestsQuery := tooDestinationOnlyRequestsFilter(role, params.Locator) + tooDestinationRequestsQuery := tooQueueOriginRequestsFilter(role, params.Locator) // Adding to an array so we can iterate over them and apply the filters after the query structure is set below options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery, tooDestinationRequestsQuery} @@ -787,7 +787,10 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption } } -func tooDestinationOnlyRequestsFilter(role roles.RoleType, locator *string) QueryOption { +// We want to filter out any moves that have ONLY destination type requests to them, such as destination SIT, shuttle, out of the +// task order queue. If the moves have origin SIT, excess weight risks, or sit extensions, they should still appear in the task order +// queue, which is what this query looks for +func tooQueueOriginRequestsFilter(role roles.RoleType, locator *string) QueryOption { return func(query *pop.Query) { if role == roles.RoleTypeTOO { baseQuery := ` From e06b9615eec61750d6ea558a13935e7988052be0 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 13 Jan 2025 20:56:13 +0000 Subject: [PATCH 17/26] update query to account for UB excess weight warning needing review --- pkg/services/order/order_fetcher.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index c0c54ce9524..114ecbeebf2 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -802,6 +802,10 @@ func tooQueueOriginRequestsFilter(role roles.RoleType, locator *string) QueryOpt ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') ) OR + ( + ((moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') + ) + OR ( ((sit_extensions.mto_shipment_id IS NOT NULL) AND sit_extensions.status = 'PENDING') ) From 25b666dfdbd361f7572fa366f9562d6e5ef139c4 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 13 Jan 2025 21:39:58 +0000 Subject: [PATCH 18/26] Revert "update query to account for UB excess weight warning needing review" This reverts commit bf88d9478c13dbf8ebc2c611ce13895b7cac6c44. --- pkg/services/order/order_fetcher.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 114ecbeebf2..c0c54ce9524 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -802,10 +802,6 @@ func tooQueueOriginRequestsFilter(role roles.RoleType, locator *string) QueryOpt ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') ) OR - ( - ((moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') - ) - OR ( ((sit_extensions.mto_shipment_id IS NOT NULL) AND sit_extensions.status = 'PENDING') ) From bbd2951a5ce65f0228cdb2c13ac6205325b5b792 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Mon, 13 Jan 2025 22:32:12 +0000 Subject: [PATCH 19/26] update query to consider UB excess weight risk --- pkg/services/order/order_fetcher.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index c0c54ce9524..114ecbeebf2 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -802,6 +802,10 @@ func tooQueueOriginRequestsFilter(role roles.RoleType, locator *string) QueryOpt ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') ) OR + ( + ((moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') + ) + OR ( ((sit_extensions.mto_shipment_id IS NOT NULL) AND sit_extensions.status = 'PENDING') ) From 59651d58d192da37c32c84f501527a54e72143f9 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Wed, 15 Jan 2025 00:47:35 +0000 Subject: [PATCH 20/26] yay plz be nice to me query --- pkg/services/order/order_fetcher.go | 63 ++++++++++++++++------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 114ecbeebf2..c4b3ae0ca19 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -122,7 +122,7 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid tooAssignedUserQuery := tooAssignedUserFilter(params.TOOAssignedUser) sortOrderQuery := sortOrder(params.Sort, params.Order, ppmCloseoutGblocs) counselingQuery := counselingOfficeFilter(params.CounselingOffice) - tooDestinationRequestsQuery := tooQueueOriginRequestsFilter(role, params.Locator) + tooDestinationRequestsQuery := tooQueueOriginRequestsFilter(role) // Adding to an array so we can iterate over them and apply the filters after the query structure is set below options := [21]QueryOption{branchQuery, locatorQuery, dodIDQuery, emplidQuery, customerNameQuery, originDutyLocationQuery, destinationDutyLocationQuery, moveStatusQuery, gblocQuery, submittedAtQuery, appearedInTOOAtQuery, requestedMoveDateQuery, ppmTypeQuery, closeoutInitiatedQuery, closeoutLocationQuery, ppmStatusQuery, sortOrderQuery, scAssignedUserQuery, tooAssignedUserQuery, counselingQuery, tooDestinationRequestsQuery} @@ -192,10 +192,6 @@ func (f orderFetcher) ListOrders(appCtx appcontext.AppContext, officeUserID uuid } if role == roles.RoleTypeTOO { query.LeftJoin("office_users as assigned_user", "moves.too_assigned_id = assigned_user.id") - query.LeftJoin("mto_service_items", "mto_shipments.id = mto_service_items.mto_shipment_id"). - LeftJoin("re_services", "mto_service_items.re_service_id = re_services.id"). - LeftJoin("shipment_address_updates", "shipment_address_updates.shipment_id = mto_shipments.id AND shipment_address_updates.new_address_id != mto_shipments.destination_address_id"). - LeftJoin("sit_extensions", "mto_shipments.id = sit_extensions.mto_shipment_id") } if params.NeedsPPMCloseout != nil { @@ -790,32 +786,43 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption // We want to filter out any moves that have ONLY destination type requests to them, such as destination SIT, shuttle, out of the // task order queue. If the moves have origin SIT, excess weight risks, or sit extensions, they should still appear in the task order // queue, which is what this query looks for -func tooQueueOriginRequestsFilter(role roles.RoleType, locator *string) QueryOption { +func tooQueueOriginRequestsFilter(role roles.RoleType) QueryOption { return func(query *pop.Query) { if role == roles.RoleTypeTOO { baseQuery := ` - ( - (mto_service_items.status IS NULL OR (mto_service_items.status = 'SUBMITTED' AND re_services.code IN ('DOFSIT', 'DOASIT', 'DOPSIT', 'DOSHUT', 'DOSFSC', 'IOFSIT', 'IOASIT', 'IODSIT', 'IOSHUT', 'IOPSIT', 'ICRT', 'IOSFSC'))) - ) - OR - ( - ((moves.excess_weight_qualified_at IS NOT NULL AND moves.excess_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') - ) - OR - ( - ((moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL) AND moves.status = 'APPROVALS REQUESTED') - ) - OR - ( - ((sit_extensions.mto_shipment_id IS NOT NULL) AND sit_extensions.status = 'PENDING') - ) - ` - if locator != nil { - query.Where(` - (moves.locator = ?) AND ( `+baseQuery+`)`, strings.ToUpper(*locator)) - } else { - query.Where(baseQuery) - } + NOT ( + ( + -- moves with destination requests (submitted destination re_services codes) + EXISTS ( + SELECT 1 + FROM mto_service_items msi + JOIN re_services rs ON msi.re_service_id = rs.id + WHERE msi.mto_shipment_id = mto_shipments.id + AND msi.status = 'SUBMITTED' + AND rs.code IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT') + ) + -- moves with destination requests (destination address update requested) + OR + EXISTS ( + SELECT 1 + FROM shipment_address_updates sau + WHERE sau.shipment_id = mto_shipments.id + AND sau.status = 'REQUESTED' + ) + ) + + -- moves with origin requests (submitted origin re_services codes) + AND NOT EXISTS ( + SELECT 1 + FROM mto_service_items msi + JOIN re_services rs ON msi.re_service_id = rs.id + WHERE msi.mto_shipment_id = mto_shipments.id + AND msi.status = 'SUBMITTED' + AND rs.code NOT IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT') + ) + ) + ` + query.Where(baseQuery) } } } From dad02a1dc03970dcc89ad8e72ca0d75840d0c278 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Wed, 15 Jan 2025 02:16:43 +0000 Subject: [PATCH 21/26] update and expand tests --- pkg/services/order/order_fetcher_test.go | 94 +++++++++++++++++++----- 1 file changed, 74 insertions(+), 20 deletions(-) diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index f2101d283ce..0336785bf9d 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -582,15 +582,7 @@ func (suite *OrderServiceSuite) TestListOrders() { }) suite.Run("task order queue does not return move with ONLY a destination address update request", func() { - officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) - session := auth.Session{ - ApplicationName: auth.OfficeApp, - Roles: officeUser.User.Roles, - OfficeUserID: officeUser.ID, - IDToken: "fake_token", - AccessToken: "fakeAccessToken", - } - // build a move with a destination address request, should NOT appear in Task Order Queue + officeUser, _, session := setupTestData() move := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ @@ -631,20 +623,10 @@ func (suite *OrderServiceSuite) TestListOrders() { }, []factory.Trait{factory.GetTraitShipmentAddressUpdateRequested}) suite.NotNil(shipmentAddressUpdate) - // build a second move - move2 := factory.BuildMove(suite.DB(), []factory.Customization{ - { - Model: models.Move{ - Status: models.MoveStatusAPPROVALSREQUESTED, - Show: models.BoolPointer(true), - }, - }}, nil) - suite.NotNil(move2) - moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) suite.FatalNoError(err) - // even though 2 moves were created, only one will be returned from the call to List Orders since we filter out + // even though 2 moves were created, (one by setupTestData(), only one will be returned from the call to List Orders since we filter out // the one with only a shipment address update to be routed to the destination requests queue suite.Equal(1, moveCount) suite.Equal(1, len(moves)) @@ -726,6 +708,78 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, moveCount) suite.Equal(1, len(moves)) }) + + suite.Run("task order queue returns a move with excess weight flagged for review", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + now := time.Now() + // build a move with a non null ExcessWeightQualifiedAt + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + ExcessWeightQualifiedAt: &now, + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + + suite.Run("task order queue returns a move with unaccompanied baggage excess weight flagged for review", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + now := time.Now() + // build a move with a non null ExcessUnaccompaniedBaggageWeightQualifiedAt + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) } func (suite *OrderServiceSuite) TestListOrderWithAssignedUserSingle() { // Under test: ListOrders From 0e7623346621aff0f1135d14d09f1ec2d4cb05f5 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 16 Jan 2025 15:10:57 +0000 Subject: [PATCH 22/26] tidy up those test comments --- pkg/services/order/order_fetcher_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index 0336785bf9d..764b4f9b401 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -626,7 +626,7 @@ func (suite *OrderServiceSuite) TestListOrders() { moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) suite.FatalNoError(err) - // even though 2 moves were created, (one by setupTestData(), only one will be returned from the call to List Orders since we filter out + // even though 2 moves were created, one by setupTestData(), only one will be returned from the call to List Orders since we filter out // the one with only a shipment address update to be routed to the destination requests queue suite.Equal(1, moveCount) suite.Equal(1, len(moves)) @@ -642,7 +642,7 @@ func (suite *OrderServiceSuite) TestListOrders() { AccessToken: "fakeAccessToken", } - // build a move with a only origin service items + // build a move with only origin service items move := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ @@ -671,7 +671,7 @@ func (suite *OrderServiceSuite) TestListOrders() { }, nil) suite.NotNil(originSITServiceItem) - // build a move with a both origin and destination service items + // build a move with both origin and destination service items move2 := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ @@ -720,7 +720,7 @@ func (suite *OrderServiceSuite) TestListOrders() { } now := time.Now() - // build a move with a non null ExcessWeightQualifiedAt + // build a move with a ExcessWeightQualifiedAt value move := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ @@ -756,7 +756,7 @@ func (suite *OrderServiceSuite) TestListOrders() { } now := time.Now() - // build a move with a non null ExcessUnaccompaniedBaggageWeightQualifiedAt + // build a move with a ExcessUnaccompaniedBaggageWeightQualifiedAt value move := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ From 10f4e68233539428c1fd42c4adffe07d9b7fffb5 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 16 Jan 2025 22:53:17 +0000 Subject: [PATCH 23/26] anotha version of the query and even more tests --- pkg/services/order/order_fetcher.go | 61 +++- pkg/services/order/order_fetcher_test.go | 386 ++++++++++++++++++++++- 2 files changed, 431 insertions(+), 16 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index c4b3ae0ca19..7b00aa0e141 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -790,37 +790,68 @@ func tooQueueOriginRequestsFilter(role roles.RoleType) QueryOption { return func(query *pop.Query) { if role == roles.RoleTypeTOO { baseQuery := ` - NOT ( + -- check for moves with destination requests and NOT origin requests, then return the inverse for the TOO queue with the NOT wrapped around the query + NOT ( + ( + -- check for moves with destination requests ( - -- moves with destination requests (submitted destination re_services codes) + -- moves with destination SIT or shuttle submitted service items EXISTS ( + -- Destination service items SELECT 1 FROM mto_service_items msi JOIN re_services rs ON msi.re_service_id = rs.id WHERE msi.mto_shipment_id = mto_shipments.id AND msi.status = 'SUBMITTED' - AND rs.code IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT') + AND rs.code IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', + 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT') ) - -- moves with destination requests (destination address update requested) - OR - EXISTS ( + -- requested shipment address update + OR EXISTS ( + -- Shipment address updates (destination address update requested) SELECT 1 FROM shipment_address_updates sau WHERE sau.shipment_id = mto_shipments.id AND sau.status = 'REQUESTED' ) ) - - -- moves with origin requests (submitted origin re_services codes) - AND NOT EXISTS ( - SELECT 1 - FROM mto_service_items msi - JOIN re_services rs ON msi.re_service_id = rs.id - WHERE msi.mto_shipment_id = mto_shipments.id - AND msi.status = 'SUBMITTED' - AND rs.code NOT IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT') + -- check for moves with origin requests or conditions where move should appear in TOO queue + AND NOT ( + -- moves with origin submitted service items + EXISTS ( + SELECT 1 + FROM mto_service_items msi + JOIN re_services rs ON msi.re_service_id = rs.id + WHERE msi.mto_shipment_id = mto_shipments.id + AND msi.status = 'SUBMITTED' + AND rs.code IN ('ICRT', 'IUBPK', 'IOFSIT', 'IOASIT', 'IOPSIT', 'IOSHUT', + 'IHUPK', 'IUCRT', 'DCRT', 'MS', 'CS', 'DOFSIT', 'DOASIT', + 'DOPSIT', 'DOSFSC', 'IOSFSC', 'DUPK', 'DUCRT', 'DOSHUT', + 'FSC', 'DMHF', 'DBTF', 'DBHF', 'IBTF', 'IBHF', 'DCRTSA', + 'DLH', 'DOP', 'DPK', 'DSH', 'DNPK', 'INPK', 'UBP', + 'ISLH', 'POEFSC', 'PODFSC', 'IHPK') + ) + OR ( + -- moves with excess weight risk to acknowledge + moves.excess_weight_qualified_at IS NOT NULL + AND moves.excess_weight_acknowledged_at IS NULL + ) + OR ( + -- moves with UB excess weight risk to acknowledge + moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL + AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL + ) + OR EXISTS ( + -- moves with SIT extension to review + SELECT 1 + FROM sit_extensions se + WHERE se.mto_shipment_id = mto_shipments.id + AND se.status = 'PENDING' + ) ) ) + ) + ` query.Where(baseQuery) } diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index 764b4f9b401..47b706d31e5 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -632,6 +632,70 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, len(moves)) }) + suite.Run("task order queue returns a move with origin service items and destination address update request", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only destination shuttle service item + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + originSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOASIT, + }, + }, + }, nil) + suite.NotNil(originSITServiceItem) + + testUUID := uuid.UUID{} + shipmentAddressUpdate := factory.BuildShipmentAddressUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: models.ShipmentAddressUpdate{ + NewAddressID: testUUID, + }, + }, + }, []factory.Trait{factory.GetTraitShipmentAddressUpdateRequested}) + suite.NotNil(shipmentAddressUpdate) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + suite.Run("task order queue does not return move with ONLY requested destination SIT service items", func() { officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) session := auth.Session{ @@ -671,7 +735,7 @@ func (suite *OrderServiceSuite) TestListOrders() { }, nil) suite.NotNil(originSITServiceItem) - // build a move with both origin and destination service items + // build a move with destination service items move2 := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.Move{ @@ -709,6 +773,262 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, len(moves)) }) + suite.Run("task order queue returns a move with origin requested SIT service items", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only origin service items + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + originSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOFSIT, + }, + }, + }, nil) + suite.NotNil(originSITServiceItem) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + + suite.Run("task order queue returns a move with both origin and destination requested SIT service items", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only origin service items + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + originSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOFSIT, + }, + }, + }, nil) + suite.NotNil(originSITServiceItem) + + destinationSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDDFSIT, + }, + }, + }, nil) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.Equal(models.MTOServiceItemStatusSubmitted, destinationSITServiceItem.Status) + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + + suite.Run("task order queue returns a move with origin shuttle service item", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only origin shuttle service item + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + internationalOriginShuttleServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIOSHUT, + }, + }, + }, nil) + suite.NotNil(internationalOriginShuttleServiceItem) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + + suite.Run("task order queue does not return a move with ONLY destination shuttle service item", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only destination shuttle service item + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + domesticDestinationShuttleServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDDSHUT, + }, + }, + }, nil) + suite.NotNil(domesticDestinationShuttleServiceItem) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(0, moveCount) + suite.Equal(0, len(moves)) + }) + + suite.Run("task order queue returns a move with both origin and destination shuttle service item", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only destination shuttle service item + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + domesticOriginShuttleServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOSHUT, + }, + }, + }, nil) + suite.NotNil(domesticOriginShuttleServiceItem) + + internationalDestinationShuttleServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDSHUT, + }, + }, + }, nil) + suite.NotNil(internationalDestinationShuttleServiceItem) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + suite.Run("task order queue returns a move with excess weight flagged for review", func() { officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) session := auth.Session{ @@ -780,6 +1100,70 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, moveCount) suite.Equal(1, len(moves)) }) + + suite.Run("task order queue returns a move with a pending SIT extension to review", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with origin service items + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + originSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + }, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOFSIT, + }, + }, + }, nil) + suite.NotNil(originSITServiceItem) + sitExtension := factory.BuildSITDurationUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.SITDurationUpdate{ + Status: models.SITExtensionStatusPending, + }, + }, + }, nil) + suite.NotNil(sitExtension) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) + } func (suite *OrderServiceSuite) TestListOrderWithAssignedUserSingle() { // Under test: ListOrders From 522c15ece0f7702e09001768b2370cc8e25051f6 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Fri, 17 Jan 2025 20:49:55 +0000 Subject: [PATCH 24/26] add test coverage for pkg/unit/millicents --- pkg/unit/millicents_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/unit/millicents_test.go b/pkg/unit/millicents_test.go index 0e7056f5f66..d7af7278abe 100644 --- a/pkg/unit/millicents_test.go +++ b/pkg/unit/millicents_test.go @@ -4,6 +4,16 @@ import ( "testing" ) +func TestMillicents_Int64(t *testing.T) { + millicents := Millicents(250000) + result := millicents.Int64() + + expected := int64(250000) + if result != expected { + t.Errorf("wrong number of Millicents: expected %v, got %v", expected, result) + } +} + func TestMillicents_Float64(t *testing.T) { millicents := Millicents(250000) result := millicents.Float64() From 53be9eee09d163c5b8d60bf77bff421f5e1c8110 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 13 Feb 2025 00:04:33 +0000 Subject: [PATCH 25/26] update query and tests to account for new SIT extension logic --- pkg/services/order/order_fetcher.go | 61 ++++++---- pkg/services/order/order_fetcher_test.go | 136 ++++++++++++++++++++++- 2 files changed, 174 insertions(+), 23 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index 7b00aa0e141..d3820dde1d4 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -792,32 +792,56 @@ func tooQueueOriginRequestsFilter(role roles.RoleType) QueryOption { baseQuery := ` -- check for moves with destination requests and NOT origin requests, then return the inverse for the TOO queue with the NOT wrapped around the query NOT ( - ( -- check for moves with destination requests ( - -- moves with destination SIT or shuttle submitted service items + -- moves with submitted destination SIT or shuttle submitted service items EXISTS ( - -- Destination service items SELECT 1 FROM mto_service_items msi JOIN re_services rs ON msi.re_service_id = rs.id WHERE msi.mto_shipment_id = mto_shipments.id AND msi.status = 'SUBMITTED' AND rs.code IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', - 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT') + 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT', 'IDSFSC') ) -- requested shipment address update OR EXISTS ( - -- Shipment address updates (destination address update requested) SELECT 1 FROM shipment_address_updates sau WHERE sau.shipment_id = mto_shipments.id AND sau.status = 'REQUESTED' ) + -- Moves with SIT extensions and ONLY destination SIT service items we filter out of TOO queue + OR ( + EXISTS ( + SELECT 1 + FROM sit_extensions se + JOIN mto_service_items msi ON se.mto_shipment_id = msi.mto_shipment_id + JOIN re_services rs ON msi.re_service_id = rs.id + WHERE se.mto_shipment_id = mto_shipments.id + AND se.status = 'PENDING' + AND rs.code IN ('DDFSIT', 'DDASIT', 'DDDSIT', 'DDSHUT', 'DDSFSC', + 'IDFSIT', 'IDASIT', 'IDDSIT', 'IDSHUT', 'IDSFSC') + ) + -- make sure there are NO origin SIT service items (otherwise, it should be in both queues) + AND NOT EXISTS ( + SELECT 1 + FROM mto_service_items msi + JOIN re_services rs ON msi.re_service_id = rs.id + WHERE msi.mto_shipment_id = mto_shipments.id + AND msi.status = 'SUBMITTED' + AND rs.code IN ('ICRT', 'IUBPK', 'IOFSIT', 'IOASIT', 'IOPSIT', 'IOSHUT', + 'IHUPK', 'IUCRT', 'DCRT', 'MS', 'CS', 'DOFSIT', 'DOASIT', + 'DOPSIT', 'DOSFSC', 'IOSFSC', 'DUPK', 'DUCRT', 'DOSHUT', + 'FSC', 'DMHF', 'DBTF', 'DBHF', 'IBTF', 'IBHF', 'DCRTSA', + 'DLH', 'DOP', 'DPK', 'DSH', 'DNPK', 'INPK', 'UBP', + 'ISLH', 'POEFSC', 'PODFSC', 'IHPK') + ) + ) ) -- check for moves with origin requests or conditions where move should appear in TOO queue AND NOT ( - -- moves with origin submitted service items + -- keep moves in the TOO queue with origin submitted service items EXISTS ( SELECT 1 FROM mto_service_items msi @@ -831,26 +855,19 @@ func tooQueueOriginRequestsFilter(role roles.RoleType) QueryOption { 'DLH', 'DOP', 'DPK', 'DSH', 'DNPK', 'INPK', 'UBP', 'ISLH', 'POEFSC', 'PODFSC', 'IHPK') ) + -- keep moves in the TOO queue if they have an unacknowledged excess weight risk OR ( - -- moves with excess weight risk to acknowledge - moves.excess_weight_qualified_at IS NOT NULL - AND moves.excess_weight_acknowledged_at IS NULL - ) - OR ( - -- moves with UB excess weight risk to acknowledge - moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL - AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL - ) - OR EXISTS ( - -- moves with SIT extension to review - SELECT 1 - FROM sit_extensions se - WHERE se.mto_shipment_id = mto_shipments.id - AND se.status = 'PENDING' + ( + moves.excess_weight_qualified_at IS NOT NULL + AND moves.excess_weight_acknowledged_at IS NULL + ) + OR ( + moves.excess_unaccompanied_baggage_weight_qualified_at IS NOT NULL + AND moves.excess_unaccompanied_baggage_weight_acknowledged_at IS NULL + ) ) ) ) - ) ` query.Where(baseQuery) diff --git a/pkg/services/order/order_fetcher_test.go b/pkg/services/order/order_fetcher_test.go index 47b706d31e5..a56a655520a 100644 --- a/pkg/services/order/order_fetcher_test.go +++ b/pkg/services/order/order_fetcher_test.go @@ -1101,7 +1101,7 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, len(moves)) }) - suite.Run("task order queue returns a move with a pending SIT extension to review", func() { + suite.Run("task order queue returns a move with a pending SIT extension and origin service items to review", func() { officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) session := auth.Session{ ApplicationName: auth.OfficeApp, @@ -1164,6 +1164,140 @@ func (suite *OrderServiceSuite) TestListOrders() { suite.Equal(1, len(moves)) }) + suite.Run("task order queue does NOT return a move with a pending SIT extension and only destination service items to review", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with destination service items + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + destinationSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + }, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDDFSIT, + }, + }, + }, nil) + suite.NotNil(destinationSITServiceItem) + sitExtension := factory.BuildSITDurationUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.SITDurationUpdate{ + Status: models.SITExtensionStatusPending, + }, + }, + }, nil) + suite.NotNil(sitExtension) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.FatalNoError(err) + suite.Equal(0, moveCount) + suite.Equal(0, len(moves)) + }) + + suite.Run("task order queue returns a move with a pending SIT extension and BOTH origin and destination service items to review", func() { + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + session := auth.Session{ + ApplicationName: auth.OfficeApp, + Roles: officeUser.User.Roles, + OfficeUserID: officeUser.ID, + IDToken: "fake_token", + AccessToken: "fakeAccessToken", + } + + // build a move with only origin service items + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + Show: models.BoolPointer(true), + }, + }}, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + suite.NotNil(shipment) + originSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDOFSIT, + }, + }, + }, nil) + suite.NotNil(originSITServiceItem) + + destinationSITServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDDFSIT, + }, + }, + }, nil) + + sitExtension := factory.BuildSITDurationUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.SITDurationUpdate{ + Status: models.SITExtensionStatusPending, + }, + }, + }, nil) + suite.NotNil(sitExtension) + + moves, moveCount, err := orderFetcher.ListOrders(suite.AppContextWithSessionForTest(&session), officeUser.ID, roles.RoleTypeTOO, &services.ListOrderParams{}) + + suite.Equal(models.MTOServiceItemStatusSubmitted, destinationSITServiceItem.Status) + suite.FatalNoError(err) + suite.Equal(1, moveCount) + suite.Equal(1, len(moves)) + }) } func (suite *OrderServiceSuite) TestListOrderWithAssignedUserSingle() { // Under test: ListOrders From b8e55babf8bb3888a48a83955c458b78be686d81 Mon Sep 17 00:00:00 2001 From: Maria Traskowsky Date: Thu, 13 Feb 2025 16:12:56 +0000 Subject: [PATCH 26/26] add comment update for extensions --- pkg/services/order/order_fetcher.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/services/order/order_fetcher.go b/pkg/services/order/order_fetcher.go index d3820dde1d4..687be4270aa 100644 --- a/pkg/services/order/order_fetcher.go +++ b/pkg/services/order/order_fetcher.go @@ -784,8 +784,8 @@ func sortOrder(sort *string, order *string, ppmCloseoutGblocs bool) QueryOption } // We want to filter out any moves that have ONLY destination type requests to them, such as destination SIT, shuttle, out of the -// task order queue. If the moves have origin SIT, excess weight risks, or sit extensions, they should still appear in the task order -// queue, which is what this query looks for +// task order queue. If the moves have origin SIT, excess weight risks, or sit extensions with origin SIT service items, they +// should still appear in the task order queue, which is what this query looks for func tooQueueOriginRequestsFilter(role roles.RoleType) QueryOption { return func(query *pop.Query) { if role == roles.RoleTypeTOO {