From 5278ebbc0e8a1db59fdecf2314b1d4e61b445cd9 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 4 Dec 2024 19:47:24 +0000 Subject: [PATCH 01/37] Backend: Assigned User Cleanup --- pkg/handlers/ghcapi/payment_request.go | 13 +++++++++++++ .../move_task_order/move_task_order_updater.go | 3 +++ .../mto_service_item/mto_service_item_updater.go | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 622d38b1abc..58b5252db44 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -186,6 +186,7 @@ func (h UpdatePaymentRequestStatusHandler) Handle( &existingPaymentRequest, params.IfMatch, ) + if err != nil { switch err.(type) { case apperror.NotFoundError: @@ -219,6 +220,18 @@ func (h UpdatePaymentRequestStatusHandler) Handle( return paymentrequestop.NewGetPaymentRequestInternalServerError(), err } + //When approving a Payment request - remove the TIO assigned user + + move, err := models.FetchMove(appCtx.DB(), appCtx.Session(), existingPaymentRequest.MoveTaskOrderID) + if err != nil { + return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err + } + move.TIOAssignedID = nil + verrs, err := models.SaveMoveDependencies(appCtx.DB(), move) + if err != nil || verrs.HasAny() { + return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err + } + return paymentrequestop.NewUpdatePaymentRequestStatusOK().WithPayload(returnPayload), nil }) } diff --git a/pkg/services/move_task_order/move_task_order_updater.go b/pkg/services/move_task_order/move_task_order_updater.go index 2193251209f..7634e9135d6 100644 --- a/pkg/services/move_task_order/move_task_order_updater.go +++ b/pkg/services/move_task_order/move_task_order_updater.go @@ -56,6 +56,9 @@ func (o moveTaskOrderUpdater) UpdateStatusServiceCounselingCompleted(appCtx appc return err } + //When submiting a move for approval - remove the SC assigned user + move.SCAssignedID = nil + // Save the move. var verrs *validate.Errors verrs, err = appCtx.DB().ValidateAndSave(move) diff --git a/pkg/services/mto_service_item/mto_service_item_updater.go b/pkg/services/mto_service_item/mto_service_item_updater.go index b2ac848273f..f6c03985310 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -165,6 +165,13 @@ func (p *mtoServiceItemUpdater) approveOrRejectServiceItem( returnedServiceItem = *updatedServiceItem + //When updating a service item - remove the TOO assigned user + move.TOOAssignedID = nil + verrs, err := models.SaveMoveDependencies(appCtx.DB(), &move) + if err != nil || verrs.HasAny() { + return err + } + return nil }) From f0a199f8439ecb661e2e2a33d9e2e80fad4340b1 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 4 Dec 2024 19:55:23 +0000 Subject: [PATCH 02/37] Removed white space --- pkg/handlers/ghcapi/payment_request.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 58b5252db44..c8cc200062f 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -186,7 +186,6 @@ func (h UpdatePaymentRequestStatusHandler) Handle( &existingPaymentRequest, params.IfMatch, ) - if err != nil { switch err.(type) { case apperror.NotFoundError: @@ -221,7 +220,6 @@ func (h UpdatePaymentRequestStatusHandler) Handle( } //When approving a Payment request - remove the TIO assigned user - move, err := models.FetchMove(appCtx.DB(), appCtx.Session(), existingPaymentRequest.MoveTaskOrderID) if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err From fd2351d95ddced24365df805e9a1f94ff9e0e185 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 6 Dec 2024 17:46:23 +0000 Subject: [PATCH 03/37] fixed placement --- .../mto_service_item/mto_service_item_updater.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/services/mto_service_item/mto_service_item_updater.go b/pkg/services/mto_service_item/mto_service_item_updater.go index f6c03985310..04b389a5c24 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -159,19 +159,19 @@ func (p *mtoServiceItemUpdater) approveOrRejectServiceItem( } move := serviceItem.MoveTaskOrder - if _, err = p.moveRouter.ApproveOrRequestApproval(txnAppCtx, move); err != nil { + //When updating a service item - remove the TOO assigned user + move.TOOAssignedID = nil + _, err = models.SaveMoveDependencies(appCtx.DB(), &move) + if err != nil { return err } - returnedServiceItem = *updatedServiceItem - - //When updating a service item - remove the TOO assigned user - move.TOOAssignedID = nil - verrs, err := models.SaveMoveDependencies(appCtx.DB(), &move) - if err != nil || verrs.HasAny() { + if _, err = p.moveRouter.ApproveOrRequestApproval(txnAppCtx, move); err != nil { return err } + returnedServiceItem = *updatedServiceItem + return nil }) From 35b2cddbe2b5fe97884fcbfdff0e63ee550cd975 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 10 Dec 2024 22:30:18 +0000 Subject: [PATCH 04/37] TIO/TOO assigned user removal --- pkg/handlers/ghcapi/api.go | 1 + pkg/handlers/ghcapi/payment_request.go | 21 ++++++++++++++++--- .../move_task_order_updater.go | 3 +++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index 6c6a50aa10e..44b5211f301 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -265,6 +265,7 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { HandlerConfig: handlerConfig, PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), } ghcAPI.PaymentServiceItemUpdatePaymentServiceItemStatusHandler = UpdatePaymentServiceItemStatusHandler{ diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index c8cc200062f..8aab5bcfbfe 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -114,6 +114,7 @@ type UpdatePaymentRequestStatusHandler struct { handlers.HandlerConfig services.PaymentRequestStatusUpdater services.PaymentRequestFetcher + services.PaymentRequestListFetcher } // Handle updates payment requests status @@ -224,12 +225,26 @@ func (h UpdatePaymentRequestStatusHandler) Handle( if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } - move.TIOAssignedID = nil - verrs, err := models.SaveMoveDependencies(appCtx.DB(), move) - if err != nil || verrs.HasAny() { + requestList, err := h.FetchPaymentRequestListByMove(appCtx, move.Locator) + if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } + openPr := false + for _, request := range *requestList { + if request.Status != "REVIEWED" { + openPr = true + } + } + + if !openPr { + move.TIOAssignedID = nil + verrs, err := models.SaveMoveDependencies(appCtx.DB(), move) + if err != nil || verrs.HasAny() { + return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err + } + } + return paymentrequestop.NewUpdatePaymentRequestStatusOK().WithPayload(returnPayload), nil }) } diff --git a/pkg/services/move_task_order/move_task_order_updater.go b/pkg/services/move_task_order/move_task_order_updater.go index 7634e9135d6..27da4c3f005 100644 --- a/pkg/services/move_task_order/move_task_order_updater.go +++ b/pkg/services/move_task_order/move_task_order_updater.go @@ -210,6 +210,9 @@ func (o *moveTaskOrderUpdater) MakeAvailableToPrime(appCtx appcontext.AppContext return &models.Move{}, apperror.NewPreconditionFailedError(move.ID, query.StaleIdentifierError{StaleIdentifier: eTag}) } + //When approving a shipment - remove the assigned TOO user + move.TOOAssignedID = nil + // If the move is already been made available to prime, we will not need to approve and update the move, // just the provided service items. updateMove := false From 4acfe7e93ecfe5027b80114421ba71960112b738 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 11 Dec 2024 15:51:42 +0000 Subject: [PATCH 05/37] Payment Requset rejection - remove assigend user --- pkg/handlers/ghcapi/payment_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 8aab5bcfbfe..e5c13370636 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -232,7 +232,7 @@ func (h UpdatePaymentRequestStatusHandler) Handle( openPr := false for _, request := range *requestList { - if request.Status != "REVIEWED" { + if request.Status != "REVIEWED" && request.Status != "REVIEWED_AND_ALL_SERVICE_ITEMS_REJECTED" { openPr = true } } From b1b8320c8c733fb1b95c8a56bd04636935ec1290 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 11 Dec 2024 17:06:54 +0000 Subject: [PATCH 06/37] removed strings --- pkg/handlers/ghcapi/payment_request.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index e5c13370636..9996edc758c 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -232,7 +232,8 @@ func (h UpdatePaymentRequestStatusHandler) Handle( openPr := false for _, request := range *requestList { - if request.Status != "REVIEWED" && request.Status != "REVIEWED_AND_ALL_SERVICE_ITEMS_REJECTED" { + if request.Status != models.PaymentRequestStatusReviewed && + request.Status != models.PaymentRequestStatusReviewedAllRejected { openPr = true } } From 2af75325c471e75019624fe85844a39cd541d810 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 11 Dec 2024 18:44:54 +0000 Subject: [PATCH 07/37] added Test --- pkg/handlers/ghcapi/payment_request_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/handlers/ghcapi/payment_request_test.go b/pkg/handlers/ghcapi/payment_request_test.go index 3d2f116accc..c0af9b7aba9 100644 --- a/pkg/handlers/ghcapi/payment_request_test.go +++ b/pkg/handlers/ghcapi/payment_request_test.go @@ -272,6 +272,7 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { HandlerConfig: suite.HandlerConfig(), PaymentRequestStatusUpdater: statusUpdater, PaymentRequestFetcher: paymentRequestFetcher, + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), } // Validate incoming payload @@ -310,6 +311,7 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { HandlerConfig: suite.HandlerConfig(), PaymentRequestStatusUpdater: statusUpdater, PaymentRequestFetcher: paymentRequestFetcher, + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), } // Validate incoming payload @@ -407,6 +409,7 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { HandlerConfig: suite.HandlerConfig(), PaymentRequestStatusUpdater: paymentRequestStatusUpdater, PaymentRequestFetcher: paymentRequestFetcher, + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), } // Validate incoming payload From a30a370f9e21c1b53a896de873a0bd6ed5b07489 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Thu, 12 Dec 2024 20:09:10 +0000 Subject: [PATCH 08/37] Added test for test coverage --- .../payloads/model_to_payload_test.go | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index c779256f33e..f3b40c459cd 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -13,6 +13,7 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/storage/test" + "github.com/transcom/mymove/pkg/testdatagen" ) func TestOrder(_ *testing.T) { @@ -479,6 +480,7 @@ func (suite *PayloadsSuite) TestSearchMoves() { appCtx := suite.AppContextForTest() marines := models.AffiliationMARINES + spaceForce := models.AffiliationSPACEFORCE moveUSMC := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.ServiceMember{ @@ -486,14 +488,52 @@ func (suite *PayloadsSuite) TestSearchMoves() { }, }, }, nil) - + moveSF := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &spaceForce, + }, + }, + }, nil) + scheduledPickupDate := time.Date(testdatagen.GHCTestYear, time.September, 20, 0, 0, 0, 0, time.UTC) + scheduledDeliveryDate := time.Date(testdatagen.GHCTestYear, time.September, 20, 0, 0, 0, 0, time.UTC) + sitAllowance := int(90) + storageFacility := factory.BuildStorageFacility(suite.DB(), nil, nil) + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: moveSF, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + ShipmentType: models.MTOShipmentTypeHHGIntoNTSDom, + CounselorRemarks: handlers.FmtString("counselor remark"), + SITDaysAllowance: &sitAllowance, + ScheduledPickupDate: &scheduledPickupDate, + ScheduledDeliveryDate: &scheduledDeliveryDate, + }, + }, + { + Model: storageFacility, + LinkOnly: true, + }, + }, nil) + moveSF.MTOShipments = append(moveSF.MTOShipments, mtoShipment) moves := models.Moves{moveUSMC} - suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct", func() { + moveSpaceForce := models.Moves{moveSF} + suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Marine move with no shipments", func() { payload := SearchMoves(appCtx, moves) suite.IsType(payload, &ghcmessages.SearchMoves{}) suite.NotNil(payload) }) + suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Non-Marine move, a shipment, and delivery/pickup time. ", func() { + payload := SearchMoves(appCtx, moveSpaceForce) + suite.IsType(payload, &ghcmessages.SearchMoves{}) + suite.NotNil(payload) + suite.NotNil(mtoShipment) + }) } func (suite *PayloadsSuite) TestMarketCode() { From 09fa6b3bb7e9ddb47f4aa55b6b50ab46200d83c0 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Thu, 12 Dec 2024 21:16:31 +0000 Subject: [PATCH 09/37] deeper test --- .../payloads/model_to_payload_test.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index f3b40c459cd..eae6176102d 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -481,6 +481,7 @@ func (suite *PayloadsSuite) TestSearchMoves() { marines := models.AffiliationMARINES spaceForce := models.AffiliationSPACEFORCE + army := models.AffiliationARMY moveUSMC := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.ServiceMember{ @@ -495,9 +496,18 @@ func (suite *PayloadsSuite) TestSearchMoves() { }, }, }, nil) + moveA := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &army, + }, + }, + }, nil) + moveUSMC.Status = models.MoveStatusNeedsServiceCounseling scheduledPickupDate := time.Date(testdatagen.GHCTestYear, time.September, 20, 0, 0, 0, 0, time.UTC) scheduledDeliveryDate := time.Date(testdatagen.GHCTestYear, time.September, 20, 0, 0, 0, 0, time.UTC) sitAllowance := int(90) + gbloc := "LKNQ" storageFacility := factory.BuildStorageFacility(suite.DB(), nil, nil) mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ { @@ -519,9 +529,13 @@ func (suite *PayloadsSuite) TestSearchMoves() { LinkOnly: true, }, }, nil) + moveSF.MTOShipments = append(moveSF.MTOShipments, mtoShipment) + moveSF.ShipmentGBLOC = append(moveSF.ShipmentGBLOC, models.MoveToGBLOC{GBLOC: &gbloc}) + moves := models.Moves{moveUSMC} moveSpaceForce := models.Moves{moveSF} + moveArmy := models.Moves{moveA} suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Marine move with no shipments", func() { payload := SearchMoves(appCtx, moves) @@ -533,6 +547,14 @@ func (suite *PayloadsSuite) TestSearchMoves() { suite.IsType(payload, &ghcmessages.SearchMoves{}) suite.NotNil(payload) suite.NotNil(mtoShipment) + + suite.NotNil(moveA) + }) + suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Army move, with no shipments. ", func() { + payload := SearchMoves(appCtx, moveArmy) + suite.IsType(payload, &ghcmessages.SearchMoves{}) + suite.NotNil(payload) + }) } From 4622222d2253fa55b2e17068fbb3e1ddfaf0bf32 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Thu, 12 Dec 2024 23:42:53 +0000 Subject: [PATCH 10/37] Another backend test case --- .../primeapi/payloads/model_to_payload_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index 5782c851928..b2f50c9c57b 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -446,6 +446,21 @@ func (suite *PayloadsSuite) TestInternalServerError() { suite.Equal(traceID.String(), detailError.Instance.String()) } +func (suite *PayloadsSuite) TestNotImplementedError() { + traceID, _ := uuid.NewV4() + detail := "Err" + + noDetailError := NotImplementedError(nil, traceID) + suite.Equal(handlers.NotImplementedErrMessage, *noDetailError.Title) + // suite.Equal(handlers.NotImplementedErrMessage, *noDetailError.Detail) + suite.Equal(traceID.String(), noDetailError.Instance.String()) + + detailError := NotImplementedError(&detail, traceID) + suite.Equal(handlers.NotImplementedErrMessage, *detailError.Title) + suite.Equal(detail, *detailError.Detail) + suite.Equal(traceID.String(), detailError.Instance.String()) +} + func (suite *PayloadsSuite) TestGetDimension() { dimensionType := models.DimensionTypeItem dimensions := models.MTOServiceItemDimensions{ From def3c3e3eab711b569ab70efd9579d2bb20806f1 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 13 Dec 2024 16:03:52 +0000 Subject: [PATCH 11/37] Added Test cases --- .../payloads/model_to_payload_test.go | 79 ++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index b2f50c9c57b..563c6a7f72c 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -610,8 +610,11 @@ func (suite *PayloadsSuite) TestShipmentAddressUpdate() { suite.Equal(strfmt.UUID(shipmentAddressUpdate.ID.String()), result.ID) } -func (suite *PayloadsSuite) TestMTOServiceItemDCRT() { +func (suite *PayloadsSuite) TestMTOServiceItemDCRTandDOFSITandDDFSIT() { reServiceCode := models.ReServiceCodeDCRT + reServiceCodeSIT := models.ReServiceCodeDOFSIT + reServiceCodeDDFSIT := models.ReServiceCodeDDFSIT + reason := "reason" dateOfContact1 := time.Now() timeMilitary1 := "1500Z" @@ -639,11 +642,83 @@ func (suite *PayloadsSuite) TestMTOServiceItemDCRT() { }, }, } + year, month, day := time.Now().Date() + aWeekAgo := time.Date(year, month, day-7, 0, 0, 0, 0, time.UTC) + departureDate := aWeekAgo.Add(time.Hour * 24 * 30) + actualPickupAddress := factory.BuildAddress(nil, nil, []factory.Trait{factory.GetTraitAddress2}) + requestApprovalRequestedStatus := false + mtoServiceItemDOFSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCodeSIT}, + Reason: &reason, + SITDepartureDate: &departureDate, + SITEntryDate: &aWeekAgo, + SITPostalCode: models.StringPointer("90210"), + SITOriginHHGActualAddress: &actualPickupAddress, + SITCustomerContacted: &aWeekAgo, + SITRequestedDelivery: &aWeekAgo, + SITOriginHHGOriginalAddress: &models.Address{ + StreetAddress1: "dummyStreet2", + City: "dummyCity2", + State: "FL", + PostalCode: "55555", + }, + RequestedApprovalsRequestedStatus: &requestApprovalRequestedStatus, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + mtoServiceItemDDFSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCodeDDFSIT}, + Reason: &reason, + SITDepartureDate: &departureDate, + SITEntryDate: &aWeekAgo, + SITPostalCode: models.StringPointer("90210"), + SITOriginHHGActualAddress: &actualPickupAddress, + SITCustomerContacted: &aWeekAgo, + SITRequestedDelivery: &aWeekAgo, + SITOriginHHGOriginalAddress: &models.Address{ + StreetAddress1: "dummyStreet2", + City: "dummyCity2", + State: "FL", + PostalCode: "55555", + }, + RequestedApprovalsRequestedStatus: &requestApprovalRequestedStatus, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } resultDCRT := MTOServiceItem(mtoServiceItemDCRT) + resultDOFSIT := MTOServiceItem(mtoServiceItemDOFSIT) + resultDDFSIT := MTOServiceItem(mtoServiceItemDDFSIT) suite.NotNil(resultDCRT) - + suite.NotNil(resultDOFSIT) + suite.NotNil(resultDDFSIT) _, ok := resultDCRT.(*primemessages.MTOServiceItemDomesticCrating) suite.True(ok) From 27ed6a4b0467403beb3ecf988367c0db30c5d900 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 13 Dec 2024 19:39:32 +0000 Subject: [PATCH 12/37] added test case --- .../payloads/model_to_payload_test.go | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index 563c6a7f72c..a6bc9ea0945 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -517,6 +517,80 @@ func (suite *PayloadsSuite) TestPaymentRequests() { suite.Equal(len(paymentRequests), len(*result)) } +func (suite *PayloadsSuite) TestMTOShipmentWithoutServiceItems() { + // Create the addresses + pickupAddress := factory.BuildAddress(suite.DB(), nil, nil) + destinationAddress := factory.BuildAddress(suite.DB(), nil, nil) + destinationType := models.DestinationTypeHomeOfRecord + secondaryPickupAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress2}) + secondaryDeliveryAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress4}) + dlhTestWeight := unit.Pound(4000) + + // Create the MTOShipment with populated PickupAddress and DestinationAddress + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + DestinationType: &destinationType, + SecondaryPickupAddressID: &secondaryPickupAddress.ID, + SecondaryDeliveryAddressID: &secondaryDeliveryAddress.ID, + PrimeEstimatedWeight: models.PoundPointer(unit.Pound(980)), + PrimeActualWeight: &dlhTestWeight, + NTSRecordedWeight: models.PoundPointer(unit.Pound(249)), + }, + }, + }, nil) + value := MTOShipmentWithoutServiceItems(&mtoShipment) + suite.NotNil(value) +} + +func (suite *PayloadsSuite) TestMTOShipmentsWithoutServiceItems() { + // Create the addresses + pickupAddress := factory.BuildAddress(suite.DB(), nil, nil) + destinationAddress := factory.BuildAddress(suite.DB(), nil, nil) + destinationType := models.DestinationTypeHomeOfRecord + secondaryPickupAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress2}) + secondaryDeliveryAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress4}) + dlhTestWeight := unit.Pound(4000) + + // Create the MTOShipment + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + DestinationType: &destinationType, + SecondaryPickupAddressID: &secondaryPickupAddress.ID, + SecondaryDeliveryAddressID: &secondaryDeliveryAddress.ID, + PrimeEstimatedWeight: models.PoundPointer(unit.Pound(980)), + PrimeActualWeight: &dlhTestWeight, + NTSRecordedWeight: models.PoundPointer(unit.Pound(249)), + }, + }, + }, nil) + + // Create the MTOShipment + mtoShipmentTwo := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + DestinationType: &destinationType, + SecondaryPickupAddressID: &secondaryPickupAddress.ID, + SecondaryDeliveryAddressID: &secondaryDeliveryAddress.ID, + PrimeEstimatedWeight: models.PoundPointer(unit.Pound(980)), + PrimeActualWeight: &dlhTestWeight, + NTSRecordedWeight: models.PoundPointer(unit.Pound(249)), + }, + }, + }, nil) + shipments := models.MTOShipments{} + shipments = append(shipments, mtoShipmentTwo, mtoShipment) + value := MTOShipmentsWithoutServiceItems(&shipments) + suite.NotNil(value) +} + func (suite *PayloadsSuite) TestPaymentServiceItem() { paymentServiceItem := models.PaymentServiceItem{ ID: uuid.Must(uuid.NewV4()), From 0f572e4c6e1a60fb8e0b7e862e50bb838e1301a9 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 13 Dec 2024 21:44:29 +0000 Subject: [PATCH 13/37] Added Test coverage --- .../payloads/model_to_payload_test.go | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index 13a3be15bb4..a85c93082e8 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -552,7 +552,75 @@ func (suite *PayloadsSuite) TestCreateCustomer() { suite.IsType(returnedShipmentAddressUpdate, &ghcmessages.CreatedCustomer{}) }) } +func (suite *PayloadsSuite) TestTransportationOffice() { + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ID: uuid.Must(uuid.NewV4()), + }, + }}, nil) + value := TransportationOffice(&transportationOffice) + suite.NotNil(value) +} +func (suite *PayloadsSuite) TestTransportationOffices() { + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ID: uuid.Must(uuid.NewV4()), + }, + }}, nil) + transportationOfficeTwo := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ID: uuid.Must(uuid.NewV4()), + }, + }}, nil) + list := models.TransportationOffices{} + list = append(list, transportationOffice, transportationOfficeTwo) + value := TransportationOffices(list) + suite.NotNil(value) +} +func (suite *PayloadsSuite) TestListMove() { + + marines := models.AffiliationMARINES + value := ListMove(nil) + suite.Nil(value) + moveUSMC := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &marines, + }, + }, + }, nil) + + value = ListMove(&moveUSMC) + suite.NotNil(value) +} + +func (suite *PayloadsSuite) TestListMoves() { + list := models.Moves{} + + marines := models.AffiliationMARINES + spaceForce := models.AffiliationSPACEFORCE + moveUSMC := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &marines, + }, + }, + }, nil) + moveSF := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &spaceForce, + }, + }, + }, nil) + list = append(list, moveUSMC, moveSF) + value := ListMoves(&list) + suite.NotNil(value) +} func (suite *PayloadsSuite) TestSearchMoves() { appCtx := suite.AppContextForTest() From 88a13769158949c3ba68dda85b3ff133ef7e9080 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 13 Dec 2024 23:05:59 +0000 Subject: [PATCH 14/37] Added Test Coverage --- .../payloads/model_to_payload_test.go | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index a85c93082e8..33a5b7114a8 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -21,6 +21,22 @@ func TestOrder(_ *testing.T) { Order(order) } +func (suite *PayloadsSuite) TestOrderWithMove() { + move := factory.BuildMove(suite.DB(), nil, nil) + moves := models.Moves{} + moves = append(moves, move) + order := factory.BuildOrder(nil, []factory.Customization{ + { + Model: models.Order{ + ID: uuid.Must(uuid.NewV4()), + HasDependents: *models.BoolPointer(true), + Moves: moves, + }, + }, + }, nil) + Order(&order) +} + // TestMove makes sure zero values/optional fields are handled func TestMove(t *testing.T) { _, err := Move(&models.Move{}, &test.FakeS3Storage{}) @@ -552,6 +568,13 @@ func (suite *PayloadsSuite) TestCreateCustomer() { suite.IsType(returnedShipmentAddressUpdate, &ghcmessages.CreatedCustomer{}) }) } + +func (suite *PayloadsSuite) TestMoveTaskOrder() { + move := factory.BuildMove(suite.DB(), nil, nil) + value := MoveTaskOrder(&move) + suite.NotNil(value) +} + func (suite *PayloadsSuite) TestTransportationOffice() { transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ { From 04bf15789c55457213492fdcb7fa271dc06c05db Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 13 Dec 2024 23:45:15 +0000 Subject: [PATCH 15/37] Added test Coverage --- .../payloads/model_to_payload_test.go | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index 33a5b7114a8..e02267a4760 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -14,6 +14,7 @@ import ( "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/storage/test" "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" ) func TestOrder(_ *testing.T) { @@ -37,6 +38,74 @@ func (suite *PayloadsSuite) TestOrderWithMove() { Order(&order) } +func (suite *PayloadsSuite) TestBoatShipment() { + boat := factory.BuildBoatShipment(suite.DB(), nil, nil) + value := BoatShipment(nil, &boat) + suite.NotNil(value) + +} + +func (suite *PayloadsSuite) TestMobileHomeShipment() { + mobileHome := factory.BuildMobileHomeShipment(suite.DB(), nil, nil) + value := MobileHomeShipment(nil, &mobileHome) + suite.NotNil(value) +} + +func (suite *PayloadsSuite) TestMovingExpense() { + contractExpense := models.MovingExpenseReceiptTypeContractedExpense + weightStored := 2000 + sitLocation := models.SITLocationTypeDestination + sitReimburseableAmount := 500 + + movingExpense := models.MovingExpense{ + PPMShipmentID: uuid.Must(uuid.NewV4()), + DocumentID: uuid.Must(uuid.NewV4()), + MovingExpenseType: &contractExpense, + Reason: models.StringPointer("no good"), + SITStartDate: models.TimePointer(time.Now()), + SITEndDate: models.TimePointer(time.Now()), + WeightStored: (*unit.Pound)(&weightStored), + SITLocation: &sitLocation, + SITReimburseableAmount: (*unit.Cents)(&sitReimburseableAmount), + } + value := MovingExpense(nil, &movingExpense) + suite.NotNil(value) +} + +func (suite *PayloadsSuite) TestMovingExpenses() { + contractExpense := models.MovingExpenseReceiptTypeContractedExpense + weightStored := 2000 + sitLocation := models.SITLocationTypeDestination + sitReimburseableAmount := 500 + movingExpenses := models.MovingExpenses{} + + movingExpense := models.MovingExpense{ + PPMShipmentID: uuid.Must(uuid.NewV4()), + DocumentID: uuid.Must(uuid.NewV4()), + MovingExpenseType: &contractExpense, + Reason: models.StringPointer("no good"), + SITStartDate: models.TimePointer(time.Now()), + SITEndDate: models.TimePointer(time.Now()), + WeightStored: (*unit.Pound)(&weightStored), + SITLocation: &sitLocation, + SITReimburseableAmount: (*unit.Cents)(&sitReimburseableAmount), + } + movingExpenseTwo := models.MovingExpense{ + PPMShipmentID: uuid.Must(uuid.NewV4()), + DocumentID: uuid.Must(uuid.NewV4()), + MovingExpenseType: &contractExpense, + Reason: models.StringPointer("no good"), + SITStartDate: models.TimePointer(time.Now()), + SITEndDate: models.TimePointer(time.Now()), + WeightStored: (*unit.Pound)(&weightStored), + SITLocation: &sitLocation, + SITReimburseableAmount: (*unit.Cents)(&sitReimburseableAmount), + } + movingExpenses = append(movingExpenses, movingExpense, movingExpenseTwo) + value := MovingExpenses(nil, movingExpenses) + suite.NotNil(value) +} + // TestMove makes sure zero values/optional fields are handled func TestMove(t *testing.T) { _, err := Move(&models.Move{}, &test.FakeS3Storage{}) From b7896a94b38e41f5c734fd64cb7b9c9afbe77540 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 17 Dec 2024 00:36:09 +0000 Subject: [PATCH 16/37] Added TIO removal test case --- pkg/factory/move_factory.go | 13 +++- pkg/factory/shared.go | 8 ++ pkg/handlers/ghcapi/api.go | 9 ++- pkg/handlers/ghcapi/payment_request.go | 9 ++- pkg/handlers/ghcapi/payment_request_test.go | 81 +++++++++++++++++---- 5 files changed, 96 insertions(+), 24 deletions(-) diff --git a/pkg/factory/move_factory.go b/pkg/factory/move_factory.go index e2192ae93f0..a3659d3bae2 100644 --- a/pkg/factory/move_factory.go +++ b/pkg/factory/move_factory.go @@ -35,6 +35,14 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode closeoutOffice = BuildTransportationOffice(db, tempCloseoutOfficeCustoms, nil) } + var tioAssignedUser models.OfficeUser + temptioAssignedUserCustoms := customs + tioAssignedUserResult := findValidCustomization(customs, OfficeUsers.TIOAssignedUser) + if tioAssignedUserResult != nil { + temptioAssignedUserCustoms = convertCustomizationInList(temptioAssignedUserCustoms, OfficeUsers.TIOAssignedUser, OfficeUser) + tioAssignedUser = BuildOfficeUser(db, temptioAssignedUserCustoms, nil) + } + var defaultReferenceID string var err error if db != nil { @@ -72,7 +80,10 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.CloseoutOffice = &closeoutOffice move.CloseoutOfficeID = &closeoutOffice.ID } - + if tioAssignedUserResult != nil { + move.TIOAssignedUser = &tioAssignedUser + move.TIOAssignedID = &tioAssignedUser.ID + } // Overwrite values with those from assertions testdatagen.MergeModels(&move, cMove) diff --git a/pkg/factory/shared.go b/pkg/factory/shared.go index 7b76ce0529c..677b7e01a03 100644 --- a/pkg/factory/shared.go +++ b/pkg/factory/shared.go @@ -263,6 +263,14 @@ var TransportationOffices = transportationOfficeGroup{ CloseoutOffice: "CloseoutOffice", } +type officeUserGroup struct { + TIOAssignedUser CustomType +} + +var OfficeUsers = officeUserGroup{ + TIOAssignedUser: "TIOAssignedUser", +} + // uploadGroup is a grouping of all the upload related fields type uploadGroup struct { UploadTypePrime CustomType diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index 78eedf347e0..2e1ba17a2d0 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -267,10 +267,11 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { } ghcAPI.PaymentRequestsUpdatePaymentRequestStatusHandler = UpdatePaymentRequestStatusHandler{ - HandlerConfig: handlerConfig, - PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), - PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + HandlerConfig: handlerConfig, + PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), + PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, } ghcAPI.PaymentServiceItemUpdatePaymentServiceItemStatusHandler = UpdatePaymentServiceItemStatusHandler{ diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 9996edc758c..ac1b465118a 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -18,6 +18,7 @@ import ( "github.com/transcom/mymove/pkg/handlers" "github.com/transcom/mymove/pkg/handlers/ghcapi/internal/payloads" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services" "github.com/transcom/mymove/pkg/services/audit" "github.com/transcom/mymove/pkg/services/event" @@ -115,6 +116,7 @@ type UpdatePaymentRequestStatusHandler struct { services.PaymentRequestStatusUpdater services.PaymentRequestFetcher services.PaymentRequestListFetcher + services.MoveAssignedOfficeUserUpdater } // Handle updates payment requests status @@ -239,11 +241,12 @@ func (h UpdatePaymentRequestStatusHandler) Handle( } if !openPr { - move.TIOAssignedID = nil - verrs, err := models.SaveMoveDependencies(appCtx.DB(), move) - if err != nil || verrs.HasAny() { + + _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, move.ID, roles.RoleTypeTIO) + if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } + returnPayload.MoveTaskOrder.TIOAssignedUser = nil } return paymentrequestop.NewUpdatePaymentRequestStatusOK().WithPayload(returnPayload), nil diff --git a/pkg/handlers/ghcapi/payment_request_test.go b/pkg/handlers/ghcapi/payment_request_test.go index c0af9b7aba9..d0a905ba8de 100644 --- a/pkg/handlers/ghcapi/payment_request_test.go +++ b/pkg/handlers/ghcapi/payment_request_test.go @@ -18,6 +18,7 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services/mocks" + "github.com/transcom/mymove/pkg/services/move" paymentrequest "github.com/transcom/mymove/pkg/services/payment_request" "github.com/transcom/mymove/pkg/services/query" "github.com/transcom/mymove/pkg/trace" @@ -228,17 +229,25 @@ func (suite *HandlerSuite) TestGetPaymentRequestsForMoveHandler() { func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { paymentRequestID, _ := uuid.FromString("00000000-0000-0000-0000-000000000001") - officeUserUUID, _ := uuid.NewV4() setupTestData := func() models.OfficeUser { - officeUser := factory.BuildOfficeUser(nil, []factory.Customization{ - {Model: models.OfficeUser{ - ID: officeUserUUID, - }}, + + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ProvidesCloseout: true, + }, + }, }, nil) - officeUser.User.Roles = append(officeUser.User.Roles, roles.Role{ - RoleType: roles.RoleTypeTIO, - }) + + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{ + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CloseoutOffice, + }, + }, []roles.RoleType{roles.RoleTypeTIO}) + return officeUser } paymentRequest := models.PaymentRequest{ @@ -250,7 +259,45 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { } statusUpdater := paymentrequest.NewPaymentRequestStatusUpdater(query.NewQueryBuilder()) + suite.Run("successful status update payment request and remove assigned user", func() { + officeUser := setupTestData() + pendingPaymentRequest := factory.BuildPaymentRequest(suite.DB(), []factory.Customization{ + { + Model: officeUser, + LinkOnly: true, + Type: &factory.OfficeUsers.TIOAssignedUser, + }, + }, nil) + + suite.NotNil(pendingPaymentRequest.MoveTaskOrder.TIOAssignedID) + + paymentRequestFetcher := &mocks.PaymentRequestFetcher{} + paymentRequestFetcher.On("FetchPaymentRequest", mock.AnythingOfType("*appcontext.appContext"), + mock.Anything).Return(pendingPaymentRequest, nil).Once() + req := httptest.NewRequest("PATCH", fmt.Sprintf("/payment_request/%s/status", pendingPaymentRequest.ID), nil) + req = suite.AuthenticateOfficeRequest(req, officeUser) + + params := paymentrequestop.UpdatePaymentRequestStatusParams{ + HTTPRequest: req, + Body: &ghcmessages.UpdatePaymentRequestStatusPayload{Status: "REVIEWED", RejectionReason: nil, ETag: etag.GenerateEtag(pendingPaymentRequest.UpdatedAt)}, + PaymentRequestID: strfmt.UUID(pendingPaymentRequest.ID.String()), + } + + handler := UpdatePaymentRequestStatusHandler{ + HandlerConfig: suite.HandlerConfig(), + PaymentRequestStatusUpdater: statusUpdater, + PaymentRequestFetcher: paymentRequestFetcher, + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, + } + + response := handler.Handle(params) + + payload := response.(*paymentrequestop.UpdatePaymentRequestStatusOK).Payload + suite.NotNil(payload.ReviewedAt) + suite.Nil(payload.MoveTaskOrder.TIOAssignedUser) + }) suite.Run("successful status update of payment request", func() { officeUser := setupTestData() pendingPaymentRequest := factory.BuildPaymentRequest(suite.DB(), nil, nil) @@ -269,10 +316,11 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { } handler := UpdatePaymentRequestStatusHandler{ - HandlerConfig: suite.HandlerConfig(), - PaymentRequestStatusUpdater: statusUpdater, - PaymentRequestFetcher: paymentRequestFetcher, - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + HandlerConfig: suite.HandlerConfig(), + PaymentRequestStatusUpdater: statusUpdater, + PaymentRequestFetcher: paymentRequestFetcher, + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, } // Validate incoming payload @@ -308,10 +356,11 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { } handler := UpdatePaymentRequestStatusHandler{ - HandlerConfig: suite.HandlerConfig(), - PaymentRequestStatusUpdater: statusUpdater, - PaymentRequestFetcher: paymentRequestFetcher, - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + HandlerConfig: suite.HandlerConfig(), + PaymentRequestStatusUpdater: statusUpdater, + PaymentRequestFetcher: paymentRequestFetcher, + PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), + MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, } // Validate incoming payload From e1fa85d4e86586b24ddbc914cf2b60f4946c1889 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 17 Dec 2024 00:50:07 +0000 Subject: [PATCH 17/37] cleaned up tests --- .../payloads/model_to_payload_test.go | 44 +++++++++---------- .../payloads/model_to_payload_test.go | 10 ++--- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index e02267a4760..9631694ed5e 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -40,15 +40,15 @@ func (suite *PayloadsSuite) TestOrderWithMove() { func (suite *PayloadsSuite) TestBoatShipment() { boat := factory.BuildBoatShipment(suite.DB(), nil, nil) - value := BoatShipment(nil, &boat) - suite.NotNil(value) + boatShipment := BoatShipment(nil, &boat) + suite.NotNil(boatShipment) } func (suite *PayloadsSuite) TestMobileHomeShipment() { mobileHome := factory.BuildMobileHomeShipment(suite.DB(), nil, nil) - value := MobileHomeShipment(nil, &mobileHome) - suite.NotNil(value) + mobileHomeShipment := MobileHomeShipment(nil, &mobileHome) + suite.NotNil(mobileHomeShipment) } func (suite *PayloadsSuite) TestMovingExpense() { @@ -68,8 +68,8 @@ func (suite *PayloadsSuite) TestMovingExpense() { SITLocation: &sitLocation, SITReimburseableAmount: (*unit.Cents)(&sitReimburseableAmount), } - value := MovingExpense(nil, &movingExpense) - suite.NotNil(value) + movingExpenseValues := MovingExpense(nil, &movingExpense) + suite.NotNil(movingExpenseValues) } func (suite *PayloadsSuite) TestMovingExpenses() { @@ -102,8 +102,8 @@ func (suite *PayloadsSuite) TestMovingExpenses() { SITReimburseableAmount: (*unit.Cents)(&sitReimburseableAmount), } movingExpenses = append(movingExpenses, movingExpense, movingExpenseTwo) - value := MovingExpenses(nil, movingExpenses) - suite.NotNil(value) + movingExpensesValue := MovingExpenses(nil, movingExpenses) + suite.NotNil(movingExpensesValue) } // TestMove makes sure zero values/optional fields are handled @@ -640,44 +640,44 @@ func (suite *PayloadsSuite) TestCreateCustomer() { func (suite *PayloadsSuite) TestMoveTaskOrder() { move := factory.BuildMove(suite.DB(), nil, nil) - value := MoveTaskOrder(&move) - suite.NotNil(value) + moveTaskOrder := MoveTaskOrder(&move) + suite.NotNil(moveTaskOrder) } func (suite *PayloadsSuite) TestTransportationOffice() { - transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + office := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ { Model: models.TransportationOffice{ ID: uuid.Must(uuid.NewV4()), }, }}, nil) - value := TransportationOffice(&transportationOffice) - suite.NotNil(value) + transportationOffice := TransportationOffice(&office) + suite.NotNil(transportationOffice) } func (suite *PayloadsSuite) TestTransportationOffices() { - transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + office := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ { Model: models.TransportationOffice{ ID: uuid.Must(uuid.NewV4()), }, }}, nil) - transportationOfficeTwo := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + officeTwo := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ { Model: models.TransportationOffice{ ID: uuid.Must(uuid.NewV4()), }, }}, nil) - list := models.TransportationOffices{} - list = append(list, transportationOffice, transportationOfficeTwo) - value := TransportationOffices(list) + transportationOfficeList := models.TransportationOffices{} + transportationOfficeList = append(transportationOfficeList, office, officeTwo) + value := TransportationOffices(transportationOfficeList) suite.NotNil(value) } func (suite *PayloadsSuite) TestListMove() { marines := models.AffiliationMARINES - value := ListMove(nil) + listMove := ListMove(nil) - suite.Nil(value) + suite.Nil(listMove) moveUSMC := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.ServiceMember{ @@ -686,8 +686,8 @@ func (suite *PayloadsSuite) TestListMove() { }, }, nil) - value = ListMove(&moveUSMC) - suite.NotNil(value) + listMove = ListMove(&moveUSMC) + suite.NotNil(listMove) } func (suite *PayloadsSuite) TestListMoves() { diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index a6bc9ea0945..8ba0c23b130 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -541,8 +541,8 @@ func (suite *PayloadsSuite) TestMTOShipmentWithoutServiceItems() { }, }, }, nil) - value := MTOShipmentWithoutServiceItems(&mtoShipment) - suite.NotNil(value) + shipmentWithoutServiceItem := MTOShipmentWithoutServiceItems(&mtoShipment) + suite.NotNil(shipmentWithoutServiceItem) } func (suite *PayloadsSuite) TestMTOShipmentsWithoutServiceItems() { @@ -585,9 +585,9 @@ func (suite *PayloadsSuite) TestMTOShipmentsWithoutServiceItems() { }, }, }, nil) - shipments := models.MTOShipments{} - shipments = append(shipments, mtoShipmentTwo, mtoShipment) - value := MTOShipmentsWithoutServiceItems(&shipments) + shipmentList := models.MTOShipments{} + shipmentList = append(shipmentList, mtoShipmentTwo, mtoShipment) + value := MTOShipmentsWithoutServiceItems(&shipmentList) suite.NotNil(value) } From a841cbea87e7c16ad30f0fcd9b5be818405df1f0 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 17 Dec 2024 15:04:17 +0000 Subject: [PATCH 18/37] PR Fixes --- pkg/factory/move_factory_test.go | 18 ++++++++++++++++++ pkg/handlers/ghcapi/payment_request.go | 8 ++++---- .../primeapi/payloads/model_to_payload_test.go | 1 - 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkg/factory/move_factory_test.go b/pkg/factory/move_factory_test.go index 4b8a86a3df0..7f5f10ec6fe 100644 --- a/pkg/factory/move_factory_test.go +++ b/pkg/factory/move_factory_test.go @@ -4,6 +4,7 @@ import ( "time" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/models/roles" ) func (suite *FactorySuite) TestBuildMove() { @@ -267,6 +268,23 @@ func (suite *FactorySuite) TestBuildMove() { suite.NotEmpty(move.MTOShipments) suite.Equal(models.MTOShipmentStatusSubmitted, move.MTOShipments[0].Status) }) + suite.Run("Successful creation of a move with an assigned TIO", func() { + officeUser := BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTIO}) + + move := BuildMoveWithShipment(suite.DB(), []Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + }, + }, + { + Model: officeUser, + LinkOnly: true, + Type: &OfficeUsers.TIOAssignedUser, + }, + }, nil) + suite.Equal(officeUser.ID, *move.TIOAssignedID) + }) suite.Run("Successful creation of customized move with shipment", func() { // Under test: BuildMoveWithShipment diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index ac1b465118a..35e9a20219f 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -232,15 +232,15 @@ func (h UpdatePaymentRequestStatusHandler) Handle( return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } - openPr := false + unreviewedPaymentRequset := false for _, request := range *requestList { if request.Status != models.PaymentRequestStatusReviewed && request.Status != models.PaymentRequestStatusReviewedAllRejected { - openPr = true + unreviewedPaymentRequset = true + break } } - - if !openPr { + if !unreviewedPaymentRequset { _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, move.ID, roles.RoleTypeTIO) if err != nil { diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index 8ba0c23b130..8d14f98b949 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -452,7 +452,6 @@ func (suite *PayloadsSuite) TestNotImplementedError() { noDetailError := NotImplementedError(nil, traceID) suite.Equal(handlers.NotImplementedErrMessage, *noDetailError.Title) - // suite.Equal(handlers.NotImplementedErrMessage, *noDetailError.Detail) suite.Equal(traceID.String(), noDetailError.Instance.String()) detailError := NotImplementedError(&detail, traceID) From 0bbc3c47db60856a160c2ed90653eb02d55d4aff Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 17 Dec 2024 16:44:17 +0000 Subject: [PATCH 19/37] PR fix - name change --- pkg/handlers/ghcapi/payment_request.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 35e9a20219f..0ca94b13582 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -232,15 +232,15 @@ func (h UpdatePaymentRequestStatusHandler) Handle( return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } - unreviewedPaymentRequset := false + paymentRequestNeedingReview := false for _, request := range *requestList { if request.Status != models.PaymentRequestStatusReviewed && request.Status != models.PaymentRequestStatusReviewedAllRejected { - unreviewedPaymentRequset = true + paymentRequestNeedingReview = true break } } - if !unreviewedPaymentRequset { + if !paymentRequestNeedingReview { _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, move.ID, roles.RoleTypeTIO) if err != nil { From a061005bcc1f9d61bc50b972c28bd83b91d5f5fd Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 17 Dec 2024 17:31:57 +0000 Subject: [PATCH 20/37] PR fix - line removal --- pkg/handlers/ghcapi/payment_request.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 0ca94b13582..bb19a7331c8 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -241,7 +241,6 @@ func (h UpdatePaymentRequestStatusHandler) Handle( } } if !paymentRequestNeedingReview { - _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, move.ID, roles.RoleTypeTIO) if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err From 90a455a4ea9e78cd90fd24f95cd6101cb0660665 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 18 Dec 2024 16:13:06 +0000 Subject: [PATCH 21/37] Validate&save --- pkg/services/mto_service_item/mto_service_item_updater.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/services/mto_service_item/mto_service_item_updater.go b/pkg/services/mto_service_item/mto_service_item_updater.go index 04b389a5c24..611c433540a 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -161,7 +161,10 @@ func (p *mtoServiceItemUpdater) approveOrRejectServiceItem( //When updating a service item - remove the TOO assigned user move.TOOAssignedID = nil - _, err = models.SaveMoveDependencies(appCtx.DB(), &move) + verrs, err := appCtx.DB().ValidateAndSave(&move) + if verrs != nil && verrs.HasAny() { + return apperror.NewInvalidInputError(move.ID, nil, verrs, "") + } if err != nil { return err } From 9714cdf310d0c842c500a1f1556733d1dba8084c Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 18 Dec 2024 19:26:48 +0000 Subject: [PATCH 22/37] Proper TOO service item removal --- pkg/models/move.go | 18 +++++++++++++++++ .../mto_service_item_updater.go | 20 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pkg/models/move.go b/pkg/models/move.go index 23c1dd7c479..f3aefca3e51 100644 --- a/pkg/models/move.go +++ b/pkg/models/move.go @@ -413,6 +413,24 @@ func SaveMoveDependencies(db *pop.Connection, move *Move) (*validate.Errors, err return responseVErrors, responseError } +// FetchMoveByMoveIDWithServiceItems returns a Move along with all the associations needed to determine +// the move service item's status. +func FetchMoveByMoveIDWithServiceItems(db *pop.Connection, moveID uuid.UUID) (Move, error) { + var move Move + err := db.Q().Eager( + "MTOServiceItems", + "MTOServiceItems.Status", + ).Where("show = TRUE").Find(&move, moveID) + + if err != nil { + if errors.Cause(err).Error() == RecordNotFoundErrorString { + return Move{}, ErrFetchNotFound + } + return Move{}, err + } + return move, nil +} + // FetchMoveForMoveDates returns a Move along with all the associations needed to determine // the move dates summary information. func FetchMoveForMoveDates(db *pop.Connection, moveID uuid.UUID) (Move, error) { diff --git a/pkg/services/mto_service_item/mto_service_item_updater.go b/pkg/services/mto_service_item/mto_service_item_updater.go index 611c433540a..1eb06ebd6c3 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -157,10 +157,28 @@ func (p *mtoServiceItemUpdater) approveOrRejectServiceItem( if err != nil { return err } + move := serviceItem.MoveTaskOrder + moveWithServiceItems, err := models.FetchMoveByMoveIDWithServiceItems(txnAppCtx.DB(), move.ID) + if err != nil { + return err + } + + serviceItemsNeedingReview := false + for _, request := range moveWithServiceItems.MTOServiceItems { + if request.Status != models.MTOServiceItemStatusApproved && + request.Status != models.MTOServiceItemStatusRejected { + serviceItemsNeedingReview = true + break + } + } + + //remove assigned user when all service items have been reviewed + if !serviceItemsNeedingReview { + move.TOOAssignedID = nil + } //When updating a service item - remove the TOO assigned user - move.TOOAssignedID = nil verrs, err := appCtx.DB().ValidateAndSave(&move) if verrs != nil && verrs.HasAny() { return apperror.NewInvalidInputError(move.ID, nil, verrs, "") From 06493d5de8003a5ecb9d76ca3062217e4047e62c Mon Sep 17 00:00:00 2001 From: Paul Stonebraker Date: Wed, 18 Dec 2024 20:26:06 +0000 Subject: [PATCH 23/37] add factory stuff for SC and TOO --- pkg/factory/move_factory.go | 33 ++++++++++++++++++++++++++--- pkg/factory/move_factory_test.go | 36 ++++++++++++++++++++++++++++++++ pkg/factory/shared.go | 4 ++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/pkg/factory/move_factory.go b/pkg/factory/move_factory.go index a3659d3bae2..72ecf8d66b4 100644 --- a/pkg/factory/move_factory.go +++ b/pkg/factory/move_factory.go @@ -35,12 +35,28 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode closeoutOffice = BuildTransportationOffice(db, tempCloseoutOfficeCustoms, nil) } + var scAssignedUser models.OfficeUser + tempSCAssignedUserCustoms := customs + scAssignedUserResult := findValidCustomization(customs, OfficeUsers.SCAssignedUser) + if scAssignedUserResult != nil { + tempSCAssignedUserCustoms = convertCustomizationInList(tempSCAssignedUserCustoms, OfficeUsers.SCAssignedUser, OfficeUser) + scAssignedUser = BuildOfficeUser(db, tempSCAssignedUserCustoms, nil) + } + + var tooAssignedUser models.OfficeUser + tempTOOAssignedUserCustoms := customs + tooAssignedUserResult := findValidCustomization(customs, OfficeUsers.TOOAssignedUser) + if tooAssignedUserResult != nil { + tempTOOAssignedUserCustoms = convertCustomizationInList(tempTOOAssignedUserCustoms, OfficeUsers.TOOAssignedUser, OfficeUser) + tooAssignedUser = BuildOfficeUser(db, tempTOOAssignedUserCustoms, nil) + } + var tioAssignedUser models.OfficeUser - temptioAssignedUserCustoms := customs + tempTIOAssignedUserCustoms := customs tioAssignedUserResult := findValidCustomization(customs, OfficeUsers.TIOAssignedUser) if tioAssignedUserResult != nil { - temptioAssignedUserCustoms = convertCustomizationInList(temptioAssignedUserCustoms, OfficeUsers.TIOAssignedUser, OfficeUser) - tioAssignedUser = BuildOfficeUser(db, temptioAssignedUserCustoms, nil) + tempTIOAssignedUserCustoms = convertCustomizationInList(tempTIOAssignedUserCustoms, OfficeUsers.TIOAssignedUser, OfficeUser) + tioAssignedUser = BuildOfficeUser(db, tempTIOAssignedUserCustoms, nil) } var defaultReferenceID string @@ -80,6 +96,17 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.CloseoutOffice = &closeoutOffice move.CloseoutOfficeID = &closeoutOffice.ID } + + if scAssignedUserResult != nil { + move.SCAssignedUser = &scAssignedUser + move.SCAssignedID = &scAssignedUser.ID + } + + if tooAssignedUserResult != nil { + move.TOOAssignedUser = &tooAssignedUser + move.TOOAssignedID = &tooAssignedUser.ID + } + if tioAssignedUserResult != nil { move.TIOAssignedUser = &tioAssignedUser move.TIOAssignedID = &tioAssignedUser.ID diff --git a/pkg/factory/move_factory_test.go b/pkg/factory/move_factory_test.go index 7f5f10ec6fe..0ff821a5dc0 100644 --- a/pkg/factory/move_factory_test.go +++ b/pkg/factory/move_factory_test.go @@ -268,6 +268,42 @@ func (suite *FactorySuite) TestBuildMove() { suite.NotEmpty(move.MTOShipments) suite.Equal(models.MTOShipmentStatusSubmitted, move.MTOShipments[0].Status) }) + suite.Run("Successful creation of a move with an assigned SC", func() { + officeUser := BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeServicesCounselor}) + + move := BuildMoveWithShipment(suite.DB(), []Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + }, + }, + { + Model: officeUser, + LinkOnly: true, + Type: &OfficeUsers.SCAssignedUser, + }, + }, nil) + suite.Equal(officeUser.ID, *move.SCAssignedID) + }) + + suite.Run("Successful creation of a move with an assigned TOO", func() { + officeUser := BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTOO}) + + move := BuildMoveWithShipment(suite.DB(), []Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + }, + }, + { + Model: officeUser, + LinkOnly: true, + Type: &OfficeUsers.TOOAssignedUser, + }, + }, nil) + suite.Equal(officeUser.ID, *move.TOOAssignedID) + }) + suite.Run("Successful creation of a move with an assigned TIO", func() { officeUser := BuildOfficeUserWithRoles(suite.DB(), nil, []roles.RoleType{roles.RoleTypeTIO}) diff --git a/pkg/factory/shared.go b/pkg/factory/shared.go index 677b7e01a03..59f52644942 100644 --- a/pkg/factory/shared.go +++ b/pkg/factory/shared.go @@ -264,10 +264,14 @@ var TransportationOffices = transportationOfficeGroup{ } type officeUserGroup struct { + SCAssignedUser CustomType + TOOAssignedUser CustomType TIOAssignedUser CustomType } var OfficeUsers = officeUserGroup{ + SCAssignedUser: "SCAssignedUser", + TOOAssignedUser: "TOOAssignedUser", TIOAssignedUser: "TIOAssignedUser", } From f07c194b861b6b1af890e181ceea179e0c972b41 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 18 Dec 2024 21:56:44 +0000 Subject: [PATCH 24/37] TOO assigned user tests --- .../mto_service_item_updater.go | 3 +- .../mto_service_item_updater_test.go | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/pkg/services/mto_service_item/mto_service_item_updater.go b/pkg/services/mto_service_item/mto_service_item_updater.go index 1eb06ebd6c3..8d2c5aded1e 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -166,8 +166,7 @@ func (p *mtoServiceItemUpdater) approveOrRejectServiceItem( serviceItemsNeedingReview := false for _, request := range moveWithServiceItems.MTOServiceItems { - if request.Status != models.MTOServiceItemStatusApproved && - request.Status != models.MTOServiceItemStatusRejected { + if request.Status == models.MTOServiceItemStatusSubmitted { serviceItemsNeedingReview = true break } diff --git a/pkg/services/mto_service_item/mto_service_item_updater_test.go b/pkg/services/mto_service_item/mto_service_item_updater_test.go index f2c6889ca98..1614e5804c8 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater_test.go +++ b/pkg/services/mto_service_item/mto_service_item_updater_test.go @@ -21,6 +21,7 @@ import ( "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/handlers" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/models/roles" mocks "github.com/transcom/mymove/pkg/route/mocks" "github.com/transcom/mymove/pkg/services/address" moverouter "github.com/transcom/mymove/pkg/services/move" @@ -1783,6 +1784,50 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.Nil(serviceItem.RejectedAt) suite.NotNil(updatedServiceItem) }) + suite.Run("Handling assigned user When TOO reviews move and approves service item", func() { + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ProvidesCloseout: true, + }, + }, + }, nil) + + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{ + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CloseoutOffice, + }, + }, []roles.RoleType{roles.RoleTypeTOO}) + + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: officeUser, + LinkOnly: true, + Type: &factory.OfficeUsers.TOOAssignedUser, + }, + }, nil) + + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + + suite.NotNil(move.TOOAssignedUser) + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + err = suite.DB().Find(&serviceItem, serviceItem.ID) + suite.NoError(err) + suite.Nil(move.TOOAssignedID) + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + }) suite.Run("When TOO approves a DDDSIT service item with an existing SITDestinationFinalAddress", func() { move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) From e5d834d35a95cdac4a38ef5d74b227c18a42a5fd Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 20 Dec 2024 02:05:31 +0000 Subject: [PATCH 25/37] Unfinished Handler -> service --- pkg/handlers/ghcapi/api.go | 2 +- pkg/handlers/ghcapi/payment_request.go | 22 +++------- .../mocks/PaymentRequestListFetcher.go | 28 ++++++++++++ pkg/services/payment_request.go | 1 + .../payment_request_list_fetcher.go | 43 +++++++++++++++++++ 5 files changed, 78 insertions(+), 18 deletions(-) diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index 2e1ba17a2d0..ca33cea1dce 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -271,7 +271,7 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), - MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, + MoveAssignedOfficeUserUpdater: move.NewAssignedOfficeUserUpdater(move.NewMoveFetcher()), } ghcAPI.PaymentServiceItemUpdatePaymentServiceItemStatusHandler = UpdatePaymentServiceItemStatusHandler{ diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index bb19a7331c8..21c9ae38bc6 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -222,31 +222,19 @@ func (h UpdatePaymentRequestStatusHandler) Handle( return paymentrequestop.NewGetPaymentRequestInternalServerError(), err } - //When approving a Payment request - remove the TIO assigned user - move, err := models.FetchMove(appCtx.DB(), appCtx.Session(), existingPaymentRequest.MoveTaskOrderID) + paymnetRequest, err := h.PaymentRequestListFetcher.CheckAndRemovePaymentRequestAssignedUser(appCtx, existingPaymentRequest.MoveTaskOrderID) if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } - requestList, err := h.FetchPaymentRequestListByMove(appCtx, move.Locator) - if err != nil { - return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err - } - - paymentRequestNeedingReview := false - for _, request := range *requestList { - if request.Status != models.PaymentRequestStatusReviewed && - request.Status != models.PaymentRequestStatusReviewedAllRejected { - paymentRequestNeedingReview = true - break - } - } - if !paymentRequestNeedingReview { - _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, move.ID, roles.RoleTypeTIO) + // ---------------------- Move to Service (in progress) ----------------------------- + if !paymnetRequest { + _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, existingPaymentRequest.MoveTaskOrderID, roles.RoleTypeTIO) if err != nil { return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err } returnPayload.MoveTaskOrder.TIOAssignedUser = nil } + // ---------------------- Move to Service (in progress) ----------------------------- return paymentrequestop.NewUpdatePaymentRequestStatusOK().WithPayload(returnPayload), nil }) diff --git a/pkg/services/mocks/PaymentRequestListFetcher.go b/pkg/services/mocks/PaymentRequestListFetcher.go index ebb611a7872..f88b128b1ab 100644 --- a/pkg/services/mocks/PaymentRequestListFetcher.go +++ b/pkg/services/mocks/PaymentRequestListFetcher.go @@ -18,6 +18,34 @@ type PaymentRequestListFetcher struct { mock.Mock } +// CheckAndRemovePaymentRequestAssignedUser provides a mock function with given fields: appCtx, id +func (_m *PaymentRequestListFetcher) CheckAndRemovePaymentRequestAssignedUser(appCtx appcontext.AppContext, id uuid.UUID) (bool, error) { + ret := _m.Called(appCtx, id) + + if len(ret) == 0 { + panic("no return value specified for CheckAndRemovePaymentRequestAssignedUser") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, uuid.UUID) (bool, error)); ok { + return rf(appCtx, id) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, uuid.UUID) bool); ok { + r0 = rf(appCtx, id) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, uuid.UUID) error); ok { + r1 = rf(appCtx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // FetchPaymentRequestList provides a mock function with given fields: appCtx, officeUserID, params func (_m *PaymentRequestListFetcher) FetchPaymentRequestList(appCtx appcontext.AppContext, officeUserID uuid.UUID, params *services.FetchPaymentRequestListParams) (*models.PaymentRequests, int, error) { ret := _m.Called(appCtx, officeUserID, params) diff --git a/pkg/services/payment_request.go b/pkg/services/payment_request.go index ae7e345dc94..329c3dc29e2 100644 --- a/pkg/services/payment_request.go +++ b/pkg/services/payment_request.go @@ -38,6 +38,7 @@ type PaymentRequestShipmentRecalculator interface { type PaymentRequestListFetcher interface { FetchPaymentRequestList(appCtx appcontext.AppContext, officeUserID uuid.UUID, params *FetchPaymentRequestListParams) (*models.PaymentRequests, int, error) FetchPaymentRequestListByMove(appCtx appcontext.AppContext, locator string) (*models.PaymentRequests, error) + CheckAndRemovePaymentRequestAssignedUser(appCtx appcontext.AppContext, id uuid.UUID) (bool, error) } // PaymentRequestFetcher is the exported interface for fetching a payment request diff --git a/pkg/services/payment_request/payment_request_list_fetcher.go b/pkg/services/payment_request/payment_request_list_fetcher.go index 11f0c52805c..8c3b6841529 100644 --- a/pkg/services/payment_request/payment_request_list_fetcher.go +++ b/pkg/services/payment_request/payment_request_list_fetcher.go @@ -17,6 +17,7 @@ import ( ) type paymentRequestListFetcher struct { + services.MoveAssignedOfficeUserUpdater } var parameters = map[string]string{ @@ -221,6 +222,48 @@ func (f *paymentRequestListFetcher) FetchPaymentRequestListByMove(appCtx appcont return &paymentRequests, nil } +// rename function +func (f *paymentRequestListFetcher) CheckAndRemovePaymentRequestAssignedUser(appCtx appcontext.AppContext, id uuid.UUID) (bool, error) { + // ---------------------- Combine into one query - to only hit DB once ----------------------------- + move := models.Move{} + + err := appCtx.DB().Q().Eager( + "SignedCertifications", + "Orders.ServiceMember", + "Orders.UploadedAmendedOrders", + "CloseoutOffice", + "LockedByOfficeUser", + "AdditionalDocuments", + "AdditionalDocuments.UserUploads", + "CounselingOffice", + ).Where("show = TRUE").Find(&move, id) + if err != nil { + return true, err + } + paymentRequests, err := f.FetchPaymentRequestListByMove(appCtx, move.Locator) + // ---------------------- Combine into one query - to only hit DB once ----------------------------- + + paymentRequestNeedingReview := false + for _, request := range *paymentRequests { + if request.Status != models.PaymentRequestStatusReviewed && + request.Status != models.PaymentRequestStatusReviewedAllRejected { + paymentRequestNeedingReview = true + break + } + } + + // ---------------------- Add to handler struct ----------------------------- + // f.wer.DeleteAssignedOfficeUser(appCtx, id, roles.RoleTypeTIO) + // pr2, err := f.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, id, roles.RoleTypeTIO) + // if err != nil { + // return true, err + // } + // fmt.Println(pr2) + // ---------------------- Add to handler struct ----------------------------- + + return paymentRequestNeedingReview, err //only returning a bool because i cannot get DeleteAssignedOfficeUser to work in here +} + // fetchEDIErrorsForPaymentRequest returns the edi_error with the most recent created_at date for a payment request func fetchEDIErrorsForPaymentRequest(appCtx appcontext.AppContext, pr *models.PaymentRequest) (models.EdiError, error) { From 9b11c9da085c7666bdec1a6bcb5a73cc620e60b1 Mon Sep 17 00:00:00 2001 From: Paul Stonebraker Date: Fri, 20 Dec 2024 16:20:41 +0000 Subject: [PATCH 26/37] trying something new with service --- pkg/handlers/ghcapi/payment_request.go | 17 +------- .../mocks/PaymentRequestStatusUpdater.go | 30 +++++++++++++ pkg/services/payment_request.go | 1 + .../payment_request_status_updater.go | 42 +++++++++++++++++++ 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 21c9ae38bc6..9aa7fb1522c 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -18,7 +18,6 @@ import ( "github.com/transcom/mymove/pkg/handlers" "github.com/transcom/mymove/pkg/handlers/ghcapi/internal/payloads" "github.com/transcom/mymove/pkg/models" - "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services" "github.com/transcom/mymove/pkg/services/audit" "github.com/transcom/mymove/pkg/services/event" @@ -184,7 +183,7 @@ func (h UpdatePaymentRequestStatusHandler) Handle( } // And now let's save our updated model object using the PaymentRequestUpdater service object. - updatedPaymentRequest, err := h.PaymentRequestStatusUpdater.UpdatePaymentRequestStatus( + updatedPaymentRequest, err := h.PaymentRequestStatusUpdater.UpdatePaymentRequestStatusAndCheckAssignment( appCtx, &existingPaymentRequest, params.IfMatch, @@ -222,20 +221,6 @@ func (h UpdatePaymentRequestStatusHandler) Handle( return paymentrequestop.NewGetPaymentRequestInternalServerError(), err } - paymnetRequest, err := h.PaymentRequestListFetcher.CheckAndRemovePaymentRequestAssignedUser(appCtx, existingPaymentRequest.MoveTaskOrderID) - if err != nil { - return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err - } - // ---------------------- Move to Service (in progress) ----------------------------- - if !paymnetRequest { - _, err := h.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, existingPaymentRequest.MoveTaskOrderID, roles.RoleTypeTIO) - if err != nil { - return paymentrequestop.NewUpdatePaymentRequestStatusInternalServerError(), err - } - returnPayload.MoveTaskOrder.TIOAssignedUser = nil - } - // ---------------------- Move to Service (in progress) ----------------------------- - return paymentrequestop.NewUpdatePaymentRequestStatusOK().WithPayload(returnPayload), nil }) } diff --git a/pkg/services/mocks/PaymentRequestStatusUpdater.go b/pkg/services/mocks/PaymentRequestStatusUpdater.go index bd6542d2199..1e5ec4f94c2 100644 --- a/pkg/services/mocks/PaymentRequestStatusUpdater.go +++ b/pkg/services/mocks/PaymentRequestStatusUpdater.go @@ -44,6 +44,36 @@ func (_m *PaymentRequestStatusUpdater) UpdatePaymentRequestStatus(appCtx appcont return r0, r1 } +// UpdatePaymentRequestStatusAndCheckAssignment provides a mock function with given fields: appCtx, paymentRequest, eTag +func (_m *PaymentRequestStatusUpdater) UpdatePaymentRequestStatusAndCheckAssignment(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) { + ret := _m.Called(appCtx, paymentRequest, eTag) + + if len(ret) == 0 { + panic("no return value specified for UpdatePaymentRequestStatusAndCheckAssignment") + } + + var r0 *models.PaymentRequest + var r1 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, *models.PaymentRequest, string) (*models.PaymentRequest, error)); ok { + return rf(appCtx, paymentRequest, eTag) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, *models.PaymentRequest, string) *models.PaymentRequest); ok { + r0 = rf(appCtx, paymentRequest, eTag) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*models.PaymentRequest) + } + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, *models.PaymentRequest, string) error); ok { + r1 = rf(appCtx, paymentRequest, eTag) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewPaymentRequestStatusUpdater creates a new instance of PaymentRequestStatusUpdater. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewPaymentRequestStatusUpdater(t interface { diff --git a/pkg/services/payment_request.go b/pkg/services/payment_request.go index 329c3dc29e2..7c676dd4d2f 100644 --- a/pkg/services/payment_request.go +++ b/pkg/services/payment_request.go @@ -60,6 +60,7 @@ type PaymentRequestReviewedFetcher interface { //go:generate mockery --name PaymentRequestStatusUpdater type PaymentRequestStatusUpdater interface { UpdatePaymentRequestStatus(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) + UpdatePaymentRequestStatusAndCheckAssignment(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) } // PaymentRequestUploadCreator is the exported interface for creating a payment request upload diff --git a/pkg/services/payment_request/payment_request_status_updater.go b/pkg/services/payment_request/payment_request_status_updater.go index 5bc9f04c030..0f8a38c9e82 100644 --- a/pkg/services/payment_request/payment_request_status_updater.go +++ b/pkg/services/payment_request/payment_request_status_updater.go @@ -8,7 +8,9 @@ import ( "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/apperror" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services" + moveservice "github.com/transcom/mymove/pkg/services/move" "github.com/transcom/mymove/pkg/services/query" ) @@ -76,3 +78,43 @@ func (p *paymentRequestStatusUpdater) UpdatePaymentRequestStatus(appCtx appconte return paymentRequest, err } + +func (p *paymentRequestStatusUpdater) UpdatePaymentRequestStatusAndCheckAssignment(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) { + paymentRequests := models.PaymentRequests{} + updatedPaymentRequest, err := p.UpdatePaymentRequestStatus(appCtx, paymentRequest, eTag) + if err != nil { + return nil, err + } + // check error + moveID := updatedPaymentRequest.MoveTaskOrderID + + err = appCtx.DB().Q().InnerJoin("moves", "payment_requests.move_id = moves.id").Where("moves.id = ?", moveID).All(&paymentRequests) + // check error + paymentRequestNeedingReview := false + for _, request := range paymentRequests { + if request.Status != models.PaymentRequestStatusReviewed && + request.Status != models.PaymentRequestStatusReviewedAllRejected { + paymentRequestNeedingReview = true + break + } + } + // move := updatedPaymentRequest.MoveTaskOrder + if !paymentRequestNeedingReview { + _, err := moveservice.AssignedOfficeUserUpdater.DeleteAssignedOfficeUser(moveservice.AssignedOfficeUserUpdater{}, appCtx, moveID, roles.RoleTypeTIO) + if err != nil { + return nil, err + } + // move.TIOAssignedID = nil + // move.TIOAssignedUser = nil + + // verrs, err := appCtx.DB().ValidateAndUpdate(&move) + // if err != nil || verrs.HasAny() { + // return nil, apperror.NewInvalidInputError(move.ID, err, verrs, "") + // } + + updatedPaymentRequest.MoveTaskOrder.TIOAssignedID = nil + updatedPaymentRequest.MoveTaskOrder.TIOAssignedUser = nil + } + + return updatedPaymentRequest, err +} From bab025e2c0501c0517f4707b69d06276d1c0666e Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 20 Dec 2024 20:42:59 +0000 Subject: [PATCH 27/37] Updated Service --- pkg/handlers/ghcapi/payment_request.go | 2 +- pkg/handlers/ghcapi/payment_request_test.go | 39 ------------- pkg/services/payment_request.go | 1 - .../payment_request_status_updater.go | 58 +++++++------------ .../payment_request_status_updater_test.go | 38 ++++++++++++ 5 files changed, 61 insertions(+), 77 deletions(-) diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 9aa7fb1522c..31b730e3455 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -183,7 +183,7 @@ func (h UpdatePaymentRequestStatusHandler) Handle( } // And now let's save our updated model object using the PaymentRequestUpdater service object. - updatedPaymentRequest, err := h.PaymentRequestStatusUpdater.UpdatePaymentRequestStatusAndCheckAssignment( + updatedPaymentRequest, err := h.PaymentRequestStatusUpdater.UpdatePaymentRequestStatus( appCtx, &existingPaymentRequest, params.IfMatch, diff --git a/pkg/handlers/ghcapi/payment_request_test.go b/pkg/handlers/ghcapi/payment_request_test.go index d0a905ba8de..a796768e9d1 100644 --- a/pkg/handlers/ghcapi/payment_request_test.go +++ b/pkg/handlers/ghcapi/payment_request_test.go @@ -259,45 +259,6 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { } statusUpdater := paymentrequest.NewPaymentRequestStatusUpdater(query.NewQueryBuilder()) - suite.Run("successful status update payment request and remove assigned user", func() { - officeUser := setupTestData() - pendingPaymentRequest := factory.BuildPaymentRequest(suite.DB(), []factory.Customization{ - { - Model: officeUser, - LinkOnly: true, - Type: &factory.OfficeUsers.TIOAssignedUser, - }, - }, nil) - - suite.NotNil(pendingPaymentRequest.MoveTaskOrder.TIOAssignedID) - - paymentRequestFetcher := &mocks.PaymentRequestFetcher{} - paymentRequestFetcher.On("FetchPaymentRequest", mock.AnythingOfType("*appcontext.appContext"), - mock.Anything).Return(pendingPaymentRequest, nil).Once() - - req := httptest.NewRequest("PATCH", fmt.Sprintf("/payment_request/%s/status", pendingPaymentRequest.ID), nil) - req = suite.AuthenticateOfficeRequest(req, officeUser) - - params := paymentrequestop.UpdatePaymentRequestStatusParams{ - HTTPRequest: req, - Body: &ghcmessages.UpdatePaymentRequestStatusPayload{Status: "REVIEWED", RejectionReason: nil, ETag: etag.GenerateEtag(pendingPaymentRequest.UpdatedAt)}, - PaymentRequestID: strfmt.UUID(pendingPaymentRequest.ID.String()), - } - - handler := UpdatePaymentRequestStatusHandler{ - HandlerConfig: suite.HandlerConfig(), - PaymentRequestStatusUpdater: statusUpdater, - PaymentRequestFetcher: paymentRequestFetcher, - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), - MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, - } - - response := handler.Handle(params) - - payload := response.(*paymentrequestop.UpdatePaymentRequestStatusOK).Payload - suite.NotNil(payload.ReviewedAt) - suite.Nil(payload.MoveTaskOrder.TIOAssignedUser) - }) suite.Run("successful status update of payment request", func() { officeUser := setupTestData() pendingPaymentRequest := factory.BuildPaymentRequest(suite.DB(), nil, nil) diff --git a/pkg/services/payment_request.go b/pkg/services/payment_request.go index 7c676dd4d2f..329c3dc29e2 100644 --- a/pkg/services/payment_request.go +++ b/pkg/services/payment_request.go @@ -60,7 +60,6 @@ type PaymentRequestReviewedFetcher interface { //go:generate mockery --name PaymentRequestStatusUpdater type PaymentRequestStatusUpdater interface { UpdatePaymentRequestStatus(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) - UpdatePaymentRequestStatusAndCheckAssignment(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) } // PaymentRequestUploadCreator is the exported interface for creating a payment request upload diff --git a/pkg/services/payment_request/payment_request_status_updater.go b/pkg/services/payment_request/payment_request_status_updater.go index 0f8a38c9e82..8ed84b5479c 100644 --- a/pkg/services/payment_request/payment_request_status_updater.go +++ b/pkg/services/payment_request/payment_request_status_updater.go @@ -50,6 +50,9 @@ func (p *paymentRequestStatusUpdater) UpdatePaymentRequestStatus(appCtx appconte } } + paymentRequests := models.PaymentRequests{} + moveID := paymentRequest.MoveTaskOrderID + var verrs *validate.Errors var err error if eTag == "" { @@ -62,34 +65,11 @@ func (p *paymentRequestStatusUpdater) UpdatePaymentRequestStatus(appCtx appconte return nil, apperror.NewInvalidInputError(id, err, verrs, "") } - if err != nil { - switch err.(type) { - case query.StaleIdentifierError: - return &models.PaymentRequest{}, apperror.NewPreconditionFailedError(id, err) - } - - switch err { - case sql.ErrNoRows: - return nil, apperror.NewNotFoundError(id, "") - default: - return nil, apperror.NewQueryError("PaymentRequest", err, "") - } + Qerr := appCtx.DB().Q().InnerJoin("moves", "payment_requests.move_id = moves.id").Where("moves.id = ?", moveID).All(&paymentRequests) + if Qerr != nil { + return nil, Qerr } - return paymentRequest, err -} - -func (p *paymentRequestStatusUpdater) UpdatePaymentRequestStatusAndCheckAssignment(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) { - paymentRequests := models.PaymentRequests{} - updatedPaymentRequest, err := p.UpdatePaymentRequestStatus(appCtx, paymentRequest, eTag) - if err != nil { - return nil, err - } - // check error - moveID := updatedPaymentRequest.MoveTaskOrderID - - err = appCtx.DB().Q().InnerJoin("moves", "payment_requests.move_id = moves.id").Where("moves.id = ?", moveID).All(&paymentRequests) - // check error paymentRequestNeedingReview := false for _, request := range paymentRequests { if request.Status != models.PaymentRequestStatusReviewed && @@ -98,23 +78,29 @@ func (p *paymentRequestStatusUpdater) UpdatePaymentRequestStatusAndCheckAssignme break } } - // move := updatedPaymentRequest.MoveTaskOrder + if !paymentRequestNeedingReview { _, err := moveservice.AssignedOfficeUserUpdater.DeleteAssignedOfficeUser(moveservice.AssignedOfficeUserUpdater{}, appCtx, moveID, roles.RoleTypeTIO) if err != nil { return nil, err } - // move.TIOAssignedID = nil - // move.TIOAssignedUser = nil + paymentRequest.MoveTaskOrder.TIOAssignedID = nil + paymentRequest.MoveTaskOrder.TIOAssignedUser = nil + } - // verrs, err := appCtx.DB().ValidateAndUpdate(&move) - // if err != nil || verrs.HasAny() { - // return nil, apperror.NewInvalidInputError(move.ID, err, verrs, "") - // } + if err != nil { + switch err.(type) { + case query.StaleIdentifierError: + return &models.PaymentRequest{}, apperror.NewPreconditionFailedError(id, err) + } - updatedPaymentRequest.MoveTaskOrder.TIOAssignedID = nil - updatedPaymentRequest.MoveTaskOrder.TIOAssignedUser = nil + switch err { + case sql.ErrNoRows: + return nil, apperror.NewNotFoundError(id, "") + default: + return nil, apperror.NewQueryError("PaymentRequest", err, "") + } } - return updatedPaymentRequest, err + return paymentRequest, err } diff --git a/pkg/services/payment_request/payment_request_status_updater_test.go b/pkg/services/payment_request/payment_request_status_updater_test.go index 178f4437437..9a7aef38fc7 100644 --- a/pkg/services/payment_request/payment_request_status_updater_test.go +++ b/pkg/services/payment_request/payment_request_status_updater_test.go @@ -7,12 +7,50 @@ import ( "github.com/transcom/mymove/pkg/etag" "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services/query" "github.com/transcom/mymove/pkg/unit" ) func (suite *PaymentRequestServiceSuite) TestUpdatePaymentRequestStatus() { builder := query.NewQueryBuilder() + suite.Run("If we get a payment request pointer with a status it should update and return no ", func() { + setupTestData := func() models.OfficeUser { + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ProvidesCloseout: true, + }, + }, + }, nil) + + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{ + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CloseoutOffice, + }, + }, []roles.RoleType{roles.RoleTypeTIO}) + + return officeUser + } + officeUser := setupTestData() + paymentRequest := factory.BuildPaymentRequest(suite.DB(), []factory.Customization{ + { + Model: officeUser, + LinkOnly: true, + Type: &factory.OfficeUsers.TIOAssignedUser, + }, + }, nil) + + paymentRequest.Status = models.PaymentRequestStatusReviewed + updater := NewPaymentRequestStatusUpdater(builder) + updatedPr, err := updater.UpdatePaymentRequestStatus(suite.AppContextForTest(), &paymentRequest, etag.GenerateEtag(paymentRequest.UpdatedAt)) + + suite.NoError(err) + suite.Nil(updatedPr.MoveTaskOrder.TIOAssignedID) + suite.Nil(updatedPr.MoveTaskOrder.TIOAssignedUser) + }) suite.Run("If we get a payment request pointer with a status it should update and return no error", func() { paymentRequest := factory.BuildPaymentRequest(suite.DB(), nil, nil) From 81aa903c4b01daf48ffd694c28c1e6a292c2a591 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Fri, 20 Dec 2024 21:59:57 +0000 Subject: [PATCH 28/37] updated mocks --- .../mocks/PaymentRequestStatusUpdater.go | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/pkg/services/mocks/PaymentRequestStatusUpdater.go b/pkg/services/mocks/PaymentRequestStatusUpdater.go index 1e5ec4f94c2..bd6542d2199 100644 --- a/pkg/services/mocks/PaymentRequestStatusUpdater.go +++ b/pkg/services/mocks/PaymentRequestStatusUpdater.go @@ -44,36 +44,6 @@ func (_m *PaymentRequestStatusUpdater) UpdatePaymentRequestStatus(appCtx appcont return r0, r1 } -// UpdatePaymentRequestStatusAndCheckAssignment provides a mock function with given fields: appCtx, paymentRequest, eTag -func (_m *PaymentRequestStatusUpdater) UpdatePaymentRequestStatusAndCheckAssignment(appCtx appcontext.AppContext, paymentRequest *models.PaymentRequest, eTag string) (*models.PaymentRequest, error) { - ret := _m.Called(appCtx, paymentRequest, eTag) - - if len(ret) == 0 { - panic("no return value specified for UpdatePaymentRequestStatusAndCheckAssignment") - } - - var r0 *models.PaymentRequest - var r1 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, *models.PaymentRequest, string) (*models.PaymentRequest, error)); ok { - return rf(appCtx, paymentRequest, eTag) - } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, *models.PaymentRequest, string) *models.PaymentRequest); ok { - r0 = rf(appCtx, paymentRequest, eTag) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.PaymentRequest) - } - } - - if rf, ok := ret.Get(1).(func(appcontext.AppContext, *models.PaymentRequest, string) error); ok { - r1 = rf(appCtx, paymentRequest, eTag) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // NewPaymentRequestStatusUpdater creates a new instance of PaymentRequestStatusUpdater. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewPaymentRequestStatusUpdater(t interface { From 108e8de831863b9e78078ad4455611e2688b4d15 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Mon, 23 Dec 2024 16:39:09 +0000 Subject: [PATCH 29/37] Removed old code --- .../mocks/PaymentRequestListFetcher.go | 28 ------------- pkg/services/payment_request.go | 1 - .../payment_request_list_fetcher.go | 42 ------------------- 3 files changed, 71 deletions(-) diff --git a/pkg/services/mocks/PaymentRequestListFetcher.go b/pkg/services/mocks/PaymentRequestListFetcher.go index f88b128b1ab..ebb611a7872 100644 --- a/pkg/services/mocks/PaymentRequestListFetcher.go +++ b/pkg/services/mocks/PaymentRequestListFetcher.go @@ -18,34 +18,6 @@ type PaymentRequestListFetcher struct { mock.Mock } -// CheckAndRemovePaymentRequestAssignedUser provides a mock function with given fields: appCtx, id -func (_m *PaymentRequestListFetcher) CheckAndRemovePaymentRequestAssignedUser(appCtx appcontext.AppContext, id uuid.UUID) (bool, error) { - ret := _m.Called(appCtx, id) - - if len(ret) == 0 { - panic("no return value specified for CheckAndRemovePaymentRequestAssignedUser") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, uuid.UUID) (bool, error)); ok { - return rf(appCtx, id) - } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, uuid.UUID) bool); ok { - r0 = rf(appCtx, id) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(appcontext.AppContext, uuid.UUID) error); ok { - r1 = rf(appCtx, id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // FetchPaymentRequestList provides a mock function with given fields: appCtx, officeUserID, params func (_m *PaymentRequestListFetcher) FetchPaymentRequestList(appCtx appcontext.AppContext, officeUserID uuid.UUID, params *services.FetchPaymentRequestListParams) (*models.PaymentRequests, int, error) { ret := _m.Called(appCtx, officeUserID, params) diff --git a/pkg/services/payment_request.go b/pkg/services/payment_request.go index 329c3dc29e2..ae7e345dc94 100644 --- a/pkg/services/payment_request.go +++ b/pkg/services/payment_request.go @@ -38,7 +38,6 @@ type PaymentRequestShipmentRecalculator interface { type PaymentRequestListFetcher interface { FetchPaymentRequestList(appCtx appcontext.AppContext, officeUserID uuid.UUID, params *FetchPaymentRequestListParams) (*models.PaymentRequests, int, error) FetchPaymentRequestListByMove(appCtx appcontext.AppContext, locator string) (*models.PaymentRequests, error) - CheckAndRemovePaymentRequestAssignedUser(appCtx appcontext.AppContext, id uuid.UUID) (bool, error) } // PaymentRequestFetcher is the exported interface for fetching a payment request diff --git a/pkg/services/payment_request/payment_request_list_fetcher.go b/pkg/services/payment_request/payment_request_list_fetcher.go index 8c3b6841529..e47e71cd0dd 100644 --- a/pkg/services/payment_request/payment_request_list_fetcher.go +++ b/pkg/services/payment_request/payment_request_list_fetcher.go @@ -222,48 +222,6 @@ func (f *paymentRequestListFetcher) FetchPaymentRequestListByMove(appCtx appcont return &paymentRequests, nil } -// rename function -func (f *paymentRequestListFetcher) CheckAndRemovePaymentRequestAssignedUser(appCtx appcontext.AppContext, id uuid.UUID) (bool, error) { - // ---------------------- Combine into one query - to only hit DB once ----------------------------- - move := models.Move{} - - err := appCtx.DB().Q().Eager( - "SignedCertifications", - "Orders.ServiceMember", - "Orders.UploadedAmendedOrders", - "CloseoutOffice", - "LockedByOfficeUser", - "AdditionalDocuments", - "AdditionalDocuments.UserUploads", - "CounselingOffice", - ).Where("show = TRUE").Find(&move, id) - if err != nil { - return true, err - } - paymentRequests, err := f.FetchPaymentRequestListByMove(appCtx, move.Locator) - // ---------------------- Combine into one query - to only hit DB once ----------------------------- - - paymentRequestNeedingReview := false - for _, request := range *paymentRequests { - if request.Status != models.PaymentRequestStatusReviewed && - request.Status != models.PaymentRequestStatusReviewedAllRejected { - paymentRequestNeedingReview = true - break - } - } - - // ---------------------- Add to handler struct ----------------------------- - // f.wer.DeleteAssignedOfficeUser(appCtx, id, roles.RoleTypeTIO) - // pr2, err := f.MoveAssignedOfficeUserUpdater.DeleteAssignedOfficeUser(appCtx, id, roles.RoleTypeTIO) - // if err != nil { - // return true, err - // } - // fmt.Println(pr2) - // ---------------------- Add to handler struct ----------------------------- - - return paymentRequestNeedingReview, err //only returning a bool because i cannot get DeleteAssignedOfficeUser to work in here -} - // fetchEDIErrorsForPaymentRequest returns the edi_error with the most recent created_at date for a payment request func fetchEDIErrorsForPaymentRequest(appCtx appcontext.AppContext, pr *models.PaymentRequest) (models.EdiError, error) { From d9ca18ce0e4e6288875b0486db8ae6e3033db705 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Mon, 23 Dec 2024 20:45:30 +0000 Subject: [PATCH 30/37] fixed files --- pkg/handlers/ghcapi/api.go | 1 - pkg/handlers/ghcapi/payment_request.go | 1 - pkg/handlers/ghcapi/payment_request_test.go | 3 --- pkg/services/payment_request/payment_request_list_fetcher.go | 1 - .../payment_request/payment_request_status_updater_test.go | 2 +- 5 files changed, 1 insertion(+), 7 deletions(-) diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index ca33cea1dce..de147cc5eb8 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -270,7 +270,6 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { HandlerConfig: handlerConfig, PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), MoveAssignedOfficeUserUpdater: move.NewAssignedOfficeUserUpdater(move.NewMoveFetcher()), } diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index 31b730e3455..fe30a27a192 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -114,7 +114,6 @@ type UpdatePaymentRequestStatusHandler struct { handlers.HandlerConfig services.PaymentRequestStatusUpdater services.PaymentRequestFetcher - services.PaymentRequestListFetcher services.MoveAssignedOfficeUserUpdater } diff --git a/pkg/handlers/ghcapi/payment_request_test.go b/pkg/handlers/ghcapi/payment_request_test.go index a796768e9d1..6109d90e2a5 100644 --- a/pkg/handlers/ghcapi/payment_request_test.go +++ b/pkg/handlers/ghcapi/payment_request_test.go @@ -280,7 +280,6 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { HandlerConfig: suite.HandlerConfig(), PaymentRequestStatusUpdater: statusUpdater, PaymentRequestFetcher: paymentRequestFetcher, - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, } @@ -320,7 +319,6 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { HandlerConfig: suite.HandlerConfig(), PaymentRequestStatusUpdater: statusUpdater, PaymentRequestFetcher: paymentRequestFetcher, - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, } @@ -419,7 +417,6 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { HandlerConfig: suite.HandlerConfig(), PaymentRequestStatusUpdater: paymentRequestStatusUpdater, PaymentRequestFetcher: paymentRequestFetcher, - PaymentRequestListFetcher: paymentrequest.NewPaymentRequestListFetcher(), } // Validate incoming payload diff --git a/pkg/services/payment_request/payment_request_list_fetcher.go b/pkg/services/payment_request/payment_request_list_fetcher.go index e47e71cd0dd..11f0c52805c 100644 --- a/pkg/services/payment_request/payment_request_list_fetcher.go +++ b/pkg/services/payment_request/payment_request_list_fetcher.go @@ -17,7 +17,6 @@ import ( ) type paymentRequestListFetcher struct { - services.MoveAssignedOfficeUserUpdater } var parameters = map[string]string{ diff --git a/pkg/services/payment_request/payment_request_status_updater_test.go b/pkg/services/payment_request/payment_request_status_updater_test.go index 9a7aef38fc7..8ca36ccf5d0 100644 --- a/pkg/services/payment_request/payment_request_status_updater_test.go +++ b/pkg/services/payment_request/payment_request_status_updater_test.go @@ -14,7 +14,7 @@ import ( func (suite *PaymentRequestServiceSuite) TestUpdatePaymentRequestStatus() { builder := query.NewQueryBuilder() - suite.Run("If we get a payment request pointer with a status it should update and return no ", func() { + suite.Run("When the last payment request is updated remove the assigend user.", func() { setupTestData := func() models.OfficeUser { transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ { From 416d9e8eb4e50e38f68a2f32c0ed26c1c94bae86 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Mon, 23 Dec 2024 22:07:47 +0000 Subject: [PATCH 31/37] Added SC and TOO test cases --- .../move_task_order_updater_test.go | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/pkg/services/move_task_order/move_task_order_updater_test.go b/pkg/services/move_task_order/move_task_order_updater_test.go index bd1e001e494..70e64840772 100644 --- a/pkg/services/move_task_order/move_task_order_updater_test.go +++ b/pkg/services/move_task_order/move_task_order_updater_test.go @@ -12,6 +12,7 @@ import ( "github.com/transcom/mymove/pkg/etag" "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/models/roles" routemocks "github.com/transcom/mymove/pkg/route/mocks" "github.com/transcom/mymove/pkg/services" "github.com/transcom/mymove/pkg/services/ghcrateengine" @@ -29,6 +30,26 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdateStatusSer queryBuilder := query.NewQueryBuilder() planner := &routemocks.Planner{} ppmEstimator := &mocks.PPMEstimator{} + setupTestData := func() models.OfficeUser { + + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ProvidesCloseout: true, + }, + }, + }, nil) + + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{ + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CloseoutOffice, + }, + }, []roles.RoleType{roles.RoleTypeServicesCounselor}) + + return officeUser + } setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { mockCreator := &mocks.SignedCertificationCreator{} @@ -66,6 +87,32 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdateStatusSer moveRouter, setUpSignedCertificationCreatorMock(nil, nil), setUpSignedCertificationUpdaterMock(nil, nil), ppmEstimator, ) + suite.Run("Makes move available to Prime and Removes assigned TOO office user", func() { + session := suite.AppContextWithSessionForTest(&auth.Session{ + ApplicationName: auth.OfficeApp, + OfficeUserID: uuid.Must(uuid.NewV4()), + }) + + officeUser := setupTestData() + move := factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusNeedsServiceCounseling, + }, + }, + { + Model: officeUser, + LinkOnly: true, + Type: &factory.OfficeUsers.SCAssignedUser, + }, + }, nil) + + eTag := etag.GenerateEtag(move.UpdatedAt) + + actualMTO, err := mtoUpdater.UpdateStatusServiceCounselingCompleted(session, move.ID, eTag) + suite.NoError(err) + suite.Nil(actualMTO.SCAssignedID) + }) suite.Run("Move status is updated successfully (with HHG shipment)", func() { session := suite.AppContextWithSessionForTest(&auth.Session{ ApplicationName: auth.OfficeApp, @@ -650,6 +697,27 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_ShowHide() { func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_MakeAvailableToPrime() { ppmEstimator := &mocks.PPMEstimator{} + setupTestData := func() models.OfficeUser { + + transportationOffice := factory.BuildTransportationOffice(suite.DB(), []factory.Customization{ + { + Model: models.TransportationOffice{ + ProvidesCloseout: true, + }, + }, + }, nil) + + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{ + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CloseoutOffice, + }, + }, []roles.RoleType{roles.RoleTypeTIO}) + + return officeUser + } + setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { mockCreator := &mocks.SignedCertificationCreator{} @@ -783,6 +851,32 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_MakeAvailableTo suite.NotNil(fetchedMove.ApprovedAt) suite.Equal(models.MoveStatusAPPROVED, fetchedMove.Status) }) + suite.Run("Makes move available to Prime and Removes assigned TOO office user", func() { + queryBuilder := query.NewQueryBuilder() + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + officeUser := setupTestData() + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: officeUser, + LinkOnly: true, + Type: &factory.OfficeUsers.TOOAssignedUser, + }, + }, nil) + + serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + mtoUpdater := mt.NewMoveTaskOrderUpdater(queryBuilder, serviceItemCreator, moveRouter, setUpSignedCertificationCreatorMock(nil, nil), setUpSignedCertificationUpdaterMock(nil, nil), ppmEstimator) + eTag := etag.GenerateEtag(move.UpdatedAt) + updatedMove, err := mtoUpdater.MakeAvailableToPrime(suite.AppContextForTest(), move.ID, eTag, false, false) + + suite.NoError(err) + suite.Nil(updatedMove.TOOAssignedID) + }) suite.Run("Makes move available to Prime and only creates Move management when it's the only one specified", func() { queryBuilder := query.NewQueryBuilder() From 09ad1ed3b617f644b8f466ca0110d3203b1aca76 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Tue, 24 Dec 2024 18:00:25 +0000 Subject: [PATCH 32/37] PR changes --- pkg/handlers/ghcapi/api.go | 7 +++---- pkg/handlers/ghcapi/payment_request.go | 1 - pkg/handlers/ghcapi/payment_request_test.go | 15 ++++++--------- pkg/models/move.go | 5 +---- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index de147cc5eb8..5edc3f7e3ee 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -267,10 +267,9 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { } ghcAPI.PaymentRequestsUpdatePaymentRequestStatusHandler = UpdatePaymentRequestStatusHandler{ - HandlerConfig: handlerConfig, - PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), - PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), - MoveAssignedOfficeUserUpdater: move.NewAssignedOfficeUserUpdater(move.NewMoveFetcher()), + HandlerConfig: handlerConfig, + PaymentRequestStatusUpdater: paymentrequest.NewPaymentRequestStatusUpdater(queryBuilder), + PaymentRequestFetcher: paymentrequest.NewPaymentRequestFetcher(), } ghcAPI.PaymentServiceItemUpdatePaymentServiceItemStatusHandler = UpdatePaymentServiceItemStatusHandler{ diff --git a/pkg/handlers/ghcapi/payment_request.go b/pkg/handlers/ghcapi/payment_request.go index fe30a27a192..622d38b1abc 100644 --- a/pkg/handlers/ghcapi/payment_request.go +++ b/pkg/handlers/ghcapi/payment_request.go @@ -114,7 +114,6 @@ type UpdatePaymentRequestStatusHandler struct { handlers.HandlerConfig services.PaymentRequestStatusUpdater services.PaymentRequestFetcher - services.MoveAssignedOfficeUserUpdater } // Handle updates payment requests status diff --git a/pkg/handlers/ghcapi/payment_request_test.go b/pkg/handlers/ghcapi/payment_request_test.go index 6109d90e2a5..17136806724 100644 --- a/pkg/handlers/ghcapi/payment_request_test.go +++ b/pkg/handlers/ghcapi/payment_request_test.go @@ -18,7 +18,6 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/services/mocks" - "github.com/transcom/mymove/pkg/services/move" paymentrequest "github.com/transcom/mymove/pkg/services/payment_request" "github.com/transcom/mymove/pkg/services/query" "github.com/transcom/mymove/pkg/trace" @@ -277,10 +276,9 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { } handler := UpdatePaymentRequestStatusHandler{ - HandlerConfig: suite.HandlerConfig(), - PaymentRequestStatusUpdater: statusUpdater, - PaymentRequestFetcher: paymentRequestFetcher, - MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, + HandlerConfig: suite.HandlerConfig(), + PaymentRequestStatusUpdater: statusUpdater, + PaymentRequestFetcher: paymentRequestFetcher, } // Validate incoming payload @@ -316,10 +314,9 @@ func (suite *HandlerSuite) TestUpdatePaymentRequestStatusHandler() { } handler := UpdatePaymentRequestStatusHandler{ - HandlerConfig: suite.HandlerConfig(), - PaymentRequestStatusUpdater: statusUpdater, - PaymentRequestFetcher: paymentRequestFetcher, - MoveAssignedOfficeUserUpdater: move.AssignedOfficeUserUpdater{}, + HandlerConfig: suite.HandlerConfig(), + PaymentRequestStatusUpdater: statusUpdater, + PaymentRequestFetcher: paymentRequestFetcher, } // Validate incoming payload diff --git a/pkg/models/move.go b/pkg/models/move.go index f3aefca3e51..b523638c997 100644 --- a/pkg/models/move.go +++ b/pkg/models/move.go @@ -417,10 +417,7 @@ func SaveMoveDependencies(db *pop.Connection, move *Move) (*validate.Errors, err // the move service item's status. func FetchMoveByMoveIDWithServiceItems(db *pop.Connection, moveID uuid.UUID) (Move, error) { var move Move - err := db.Q().Eager( - "MTOServiceItems", - "MTOServiceItems.Status", - ).Where("show = TRUE").Find(&move, moveID) + err := db.Q().Eager().Where("show = TRUE").Find(&move, moveID) if err != nil { if errors.Cause(err).Error() == RecordNotFoundErrorString { From 1155ac24343f996a0809ad70c8f6741425cb3925 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 8 Jan 2025 21:56:00 +0000 Subject: [PATCH 33/37] removed tests --- .../payloads/model_to_payload_test.go | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index 7537a5a01b4..0e6b225889e 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -13,7 +13,6 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/models/roles" "github.com/transcom/mymove/pkg/storage/test" - "github.com/transcom/mymove/pkg/testdatagen" "github.com/transcom/mymove/pkg/unit" ) @@ -717,8 +716,6 @@ func (suite *PayloadsSuite) TestSearchMoves() { appCtx := suite.AppContextForTest() marines := models.AffiliationMARINES - spaceForce := models.AffiliationSPACEFORCE - army := models.AffiliationARMY moveUSMC := factory.BuildMove(suite.DB(), []factory.Customization{ { Model: models.ServiceMember{ @@ -726,73 +723,14 @@ func (suite *PayloadsSuite) TestSearchMoves() { }, }, }, nil) - moveSF := factory.BuildMove(suite.DB(), []factory.Customization{ - { - Model: models.ServiceMember{ - Affiliation: &spaceForce, - }, - }, - }, nil) - moveA := factory.BuildMove(suite.DB(), []factory.Customization{ - { - Model: models.ServiceMember{ - Affiliation: &army, - }, - }, - }, nil) - moveUSMC.Status = models.MoveStatusNeedsServiceCounseling - scheduledPickupDate := time.Date(testdatagen.GHCTestYear, time.September, 20, 0, 0, 0, 0, time.UTC) - scheduledDeliveryDate := time.Date(testdatagen.GHCTestYear, time.September, 20, 0, 0, 0, 0, time.UTC) - sitAllowance := int(90) - gbloc := "LKNQ" - storageFacility := factory.BuildStorageFacility(suite.DB(), nil, nil) - mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ - { - Model: moveSF, - LinkOnly: true, - }, - { - Model: models.MTOShipment{ - Status: models.MTOShipmentStatusApproved, - ShipmentType: models.MTOShipmentTypeHHGIntoNTSDom, - CounselorRemarks: handlers.FmtString("counselor remark"), - SITDaysAllowance: &sitAllowance, - ScheduledPickupDate: &scheduledPickupDate, - ScheduledDeliveryDate: &scheduledDeliveryDate, - }, - }, - { - Model: storageFacility, - LinkOnly: true, - }, - }, nil) - - moveSF.MTOShipments = append(moveSF.MTOShipments, mtoShipment) - moveSF.ShipmentGBLOC = append(moveSF.ShipmentGBLOC, models.MoveToGBLOC{GBLOC: &gbloc}) moves := models.Moves{moveUSMC} - moveSpaceForce := models.Moves{moveSF} - moveArmy := models.Moves{moveA} suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Marine move with no shipments", func() { payload := SearchMoves(appCtx, moves) suite.IsType(payload, &ghcmessages.SearchMoves{}) suite.NotNil(payload) }) - suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Non-Marine move, a shipment, and delivery/pickup time. ", func() { - payload := SearchMoves(appCtx, moveSpaceForce) - suite.IsType(payload, &ghcmessages.SearchMoves{}) - suite.NotNil(payload) - suite.NotNil(mtoShipment) - - suite.NotNil(moveA) - }) - suite.Run("Success - Returns a ghcmessages Upload payload from Upload Struct Army move, with no shipments. ", func() { - payload := SearchMoves(appCtx, moveArmy) - suite.IsType(payload, &ghcmessages.SearchMoves{}) - suite.NotNil(payload) - - }) } func (suite *PayloadsSuite) TestMarketCode() { From 9713b2cc944e11b5832b678603c53a7a6976f328 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Wed, 8 Jan 2025 21:59:33 +0000 Subject: [PATCH 34/37] PR comments --- pkg/factory/shared.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/factory/shared.go b/pkg/factory/shared.go index 2ff8e0dea9b..d7f5b069776 100644 --- a/pkg/factory/shared.go +++ b/pkg/factory/shared.go @@ -273,14 +273,14 @@ var TransportationOffices = transportationOfficeGroup{ type officeUserGroup struct { SCAssignedUser CustomType - TOOAssignedUser CustomType TIOAssignedUser CustomType + TOOAssignedUser CustomType } var OfficeUsers = officeUserGroup{ SCAssignedUser: "SCAssignedUser", - TOOAssignedUser: "TOOAssignedUser", TIOAssignedUser: "TIOAssignedUser", + TOOAssignedUser: "TOOAssignedUser", } // uploadGroup is a grouping of all the upload related fields From 7dfef82968c70d3fa04585bcc3c760ce599d13d8 Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Mon, 13 Jan 2025 18:59:12 +0000 Subject: [PATCH 35/37] fixced merge conflicts --- pkg/factory/move_factory.go | 4 ---- pkg/factory/shared.go | 8 -------- 2 files changed, 12 deletions(-) diff --git a/pkg/factory/move_factory.go b/pkg/factory/move_factory.go index f496c1dc5f1..4564f893657 100644 --- a/pkg/factory/move_factory.go +++ b/pkg/factory/move_factory.go @@ -35,7 +35,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode closeoutOffice = BuildTransportationOffice(db, tempCloseoutOfficeCustoms, nil) } - var counselingOffice models.TransportationOffice tempCounselingOfficeCustoms := customs counselingOfficeResult := findValidCustomization(customs, TransportationOffices.CounselingOffice) @@ -52,7 +51,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode scAssignedUser = BuildOfficeUser(db, tempSCAssignedUserCustoms, nil) } - var tooAssignedUser models.OfficeUser tempTOOAssignedUserCustoms := customs tooAssignedUserResult := findValidCustomization(customs, OfficeUsers.TOOAssignedUser) @@ -107,7 +105,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.CloseoutOfficeID = &closeoutOffice.ID } - if counselingOfficeResult != nil { move.CounselingOffice = &counselingOffice move.CounselingOfficeID = &counselingOffice.ID @@ -118,7 +115,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.SCAssignedID = &scAssignedUser.ID } - if tooAssignedUserResult != nil { move.TOOAssignedUser = &tooAssignedUser move.TOOAssignedID = &tooAssignedUser.ID diff --git a/pkg/factory/shared.go b/pkg/factory/shared.go index 8d72b513a7d..037f2d352d5 100644 --- a/pkg/factory/shared.go +++ b/pkg/factory/shared.go @@ -273,14 +273,6 @@ var TransportationOffices = transportationOfficeGroup{ CounselingOffice: "CounselingOffice", } -type officeUserGroup struct { - SCAssignedUser CustomType -} - -var OfficeUsers = officeUserGroup{ - SCAssignedUser: "SCAssignedUser", -} - type officeUserGroup struct { SCAssignedUser CustomType TIOAssignedUser CustomType From 28ce85b4a886815bcf8ab04aef1fdf39108d099b Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Mon, 13 Jan 2025 19:49:21 +0000 Subject: [PATCH 36/37] PR Fixes --- pkg/factory/move_factory.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/factory/move_factory.go b/pkg/factory/move_factory.go index 4564f893657..3f923f95204 100644 --- a/pkg/factory/move_factory.go +++ b/pkg/factory/move_factory.go @@ -35,14 +35,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode closeoutOffice = BuildTransportationOffice(db, tempCloseoutOfficeCustoms, nil) } - var counselingOffice models.TransportationOffice - tempCounselingOfficeCustoms := customs - counselingOfficeResult := findValidCustomization(customs, TransportationOffices.CounselingOffice) - if counselingOfficeResult != nil { - tempCounselingOfficeCustoms = convertCustomizationInList(tempCounselingOfficeCustoms, TransportationOffices.CounselingOffice, TransportationOffice) - counselingOffice = BuildTransportationOffice(db, tempCounselingOfficeCustoms, nil) - } - var scAssignedUser models.OfficeUser tempSCAssignedUserCustoms := customs scAssignedUserResult := findValidCustomization(customs, OfficeUsers.SCAssignedUser) @@ -67,6 +59,14 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode tioAssignedUser = BuildOfficeUser(db, tempTIOAssignedUserCustoms, nil) } + var counselingOffice models.TransportationOffice + tempCounselingOfficeCustoms := customs + counselingOfficeResult := findValidCustomization(customs, TransportationOffices.CounselingOffice) + if counselingOfficeResult != nil { + tempCounselingOfficeCustoms = convertCustomizationInList(tempCounselingOfficeCustoms, TransportationOffices.CounselingOffice, TransportationOffice) + counselingOffice = BuildTransportationOffice(db, tempCounselingOfficeCustoms, nil) + } + var defaultReferenceID string var err error if db != nil { @@ -105,11 +105,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.CloseoutOfficeID = &closeoutOffice.ID } - if counselingOfficeResult != nil { - move.CounselingOffice = &counselingOffice - move.CounselingOfficeID = &counselingOffice.ID - } - if scAssignedUserResult != nil { move.SCAssignedUser = &scAssignedUser move.SCAssignedID = &scAssignedUser.ID @@ -125,6 +120,11 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.TIOAssignedID = &tioAssignedUser.ID } + if counselingOfficeResult != nil { + move.CounselingOffice = &counselingOffice + move.CounselingOfficeID = &counselingOffice.ID + } + // Overwrite values with those from assertions testdatagen.MergeModels(&move, cMove) From a3eada6c8b3f2886c0a1ade06df1378e2d0f66ff Mon Sep 17 00:00:00 2001 From: Jon Spight Date: Mon, 13 Jan 2025 21:30:20 +0000 Subject: [PATCH 37/37] moved SC to match INT placement --- pkg/factory/move_factory.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/factory/move_factory.go b/pkg/factory/move_factory.go index 3f923f95204..8561df50127 100644 --- a/pkg/factory/move_factory.go +++ b/pkg/factory/move_factory.go @@ -105,11 +105,6 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.CloseoutOfficeID = &closeoutOffice.ID } - if scAssignedUserResult != nil { - move.SCAssignedUser = &scAssignedUser - move.SCAssignedID = &scAssignedUser.ID - } - if tooAssignedUserResult != nil { move.TOOAssignedUser = &tooAssignedUser move.TOOAssignedID = &tooAssignedUser.ID @@ -125,6 +120,11 @@ func BuildMove(db *pop.Connection, customs []Customization, traits []Trait) mode move.CounselingOfficeID = &counselingOffice.ID } + if scAssignedUserResult != nil { + move.SCAssignedUser = &scAssignedUser + move.SCAssignedID = &scAssignedUser.ID + } + // Overwrite values with those from assertions testdatagen.MergeModels(&move, cMove)