From d4e41949b98d51c929e5e9bd0cb9893b47f0c853 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Wed, 18 Dec 2024 21:04:53 +0000 Subject: [PATCH 01/10] add int changes and generate new migration file --- migrations/app/migrations_manifest.txt | 1 + ...add_international_nts_service_items.up.sql | 21 ++++ .../mto_shipment/mto_shipment_updater.go | 16 +-- .../mto_shipment/mto_shipment_updater_test.go | 105 ++++++++++++++++++ .../mto_shipment/shipment_approver.go | 19 ++-- .../mto_shipment/shipment_approver_test.go | 103 ++++++++++++++++- 6 files changed, 249 insertions(+), 16 deletions(-) create mode 100644 migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 3f453bf1226..0b91d4bfe2a 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1051,3 +1051,4 @@ 20241204155919_update_ordering_proc.up.sql 20241204210208_retroactive_update_of_ppm_max_and_estimated_incentives_prd.up.sql 20241216170325_update_nts_enum_name.up.sql +20241218204620_add_international_nts_service_items.up.sql diff --git a/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql b/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql new file mode 100644 index 00000000000..2bb5207813f --- /dev/null +++ b/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql @@ -0,0 +1,21 @@ +-- +-- Add service items for international NTS shipments. +-- +INSERT INTO re_service_items +(id, service_id, shipment_type, market_code, is_auto_approved, created_at, updated_at, sort) +VALUES + ('2a560507-db09-4be1-b809-49c0f515b31b', '9f3d551a-0725-430e-897e-80ee9add3ae9' ,'HHG_INTO_NTS', 'i', true, now(), now(), 1), + ('e702818f-defd-452c-81a3-865b902e7dd0', '388115e8-abe9-441d-96cf-a39f24baa0a3' ,'HHG_INTO_NTS', 'i', true, now(), now(), 2), + ('366ee5a4-eb61-4ded-a68c-ddc29fe1a886', '874cb86a-bc39-4f57-a614-53ee3fcacf14' ,'HHG_INTO_NTS', 'i', true, now(), now(), 3), + ('aac4e95e-27ed-4f09-9b6b-384d8542f410', '86203d72-7f7c-49ff-82f0-5b95e4958f60' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('010f2f91-7381-4149-8d74-8eb5f593a864', '806c6d59-57ff-4a3f-9518-ebf29ba9cb10' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('a41966b7-b83a-4eaf-8e68-d5e884777102', '28389ee1-56cf-400c-aa52-1501ecdd7c69' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('14c77957-3c76-465a-bb07-c98d36ef1e54', 'bd6064ca-e780-4ab4-a37b-0ae98eebb244' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('d52d2d03-100a-4ed9-b2de-16eac63a375f', '22fc07ed-be15-4f50-b941-cbd38153b378' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('7fd91408-7d69-4375-b7e6-5b2ff714206b', 'bd424e45-397b-4766-9712-de4ae3a2da36' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('b3dc509d-d652-4300-a702-a1ddce6255b6', 'b488bf85-ea5e-49c8-ba5c-e2fa278ac806' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('001eadb6-3526-45b9-96e0-0648bb481e86', '6f4f6e31-0675-4051-b659-89832259f390' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('b991c5c9-af2c-4146-b999-1d0bdf91de3f', '624a97c5-dfbf-4da9-a6e9-526b4f95af8d' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('5a89315a-257b-4ef0-92cb-4c06aa6f1332', '4132416b-b1aa-42e7-98f2-0ac0a03e8a31' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('d4a98dea-a5f7-4b92-b5de-e6350ab07824', '81e29d0c-02a6-4a7a-be02-554deb3ee49e' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + ('eaea90c2-93d3-4db9-89cd-23ac57ec9ce1', '690a5fc1-0ea5-4554-8294-a367b5daefa9' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL); diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 21b54188170..1c67d6f578a 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -1092,13 +1092,15 @@ func reServiceCodesForShipment(shipment models.MTOShipment) []models.ReServiceCo } } case models.MTOShipmentTypeHHGIntoNTS: - // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom NTS Packing - return []models.ReServiceCode{ - models.ReServiceCodeDLH, - models.ReServiceCodeFSC, - models.ReServiceCodeDOP, - models.ReServiceCodeDDP, - models.ReServiceCodeDNPK, + if shipment.MarketCode != models.MarketCodeInternational { + // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom NTS Packing + return []models.ReServiceCode{ + models.ReServiceCodeDLH, + models.ReServiceCodeFSC, + models.ReServiceCodeDOP, + models.ReServiceCodeDDP, + models.ReServiceCodeDNPK, + } } case models.MTOShipmentTypeHHGOutOfNTSDom: // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Unpacking diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 185319eb3d7..7b66c7417d3 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -3031,3 +3031,108 @@ func (suite *MTOShipmentServiceSuite) TestUpdateStatusServiceItems() { suite.Equal(models.ReServiceCodeDSH, serviceItems[0].ReService.Code) }) } + +func (suite *MTOShipmentServiceSuite) TestUpdateDomesticServiceItems() { + + expectedReServiceCodes := []models.ReServiceCode{ + models.ReServiceCodeDLH, + models.ReServiceCodeFSC, + models.ReServiceCodeDOP, + models.ReServiceCodeDDP, + models.ReServiceCodeDNPK, + } + + var pickupAddress models.Address + var storageFacility models.StorageFacility + var mto models.Move + + setupTestData := func() { + for i := range expectedReServiceCodes { + factory.FetchReServiceByCode(suite.DB(), expectedReServiceCodes[i]) + } + + pickupAddress = factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Test Street 1", + City: "Des moines", + State: "IA", + PostalCode: "50309", + IsOconus: models.BoolPointer(false), + }, + }, + }, nil) + + storageFacility = factory.BuildStorageFacility(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Test Street Adress 2", + City: "Des moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + }, + }, + }, nil) + + mto = factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + }, + }, + }, nil) + } + + builder := query.NewQueryBuilder() + moveRouter := moveservices.NewMoveRouter() + planner := &mocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + updater := NewMTOShipmentStatusUpdater(builder, siCreator, planner) + + suite.Run("Preapproved service items successfully added to domestic nts shipments", func() { + setupTestData() + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + { + Model: pickupAddress, + Type: &factory.Addresses.PickupAddress, + LinkOnly: true, + }, + { + Model: storageFacility, + Type: &factory.StorageFacility, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + ShipmentType: models.MTOShipmentTypeHHGIntoNTS, + Status: models.MTOShipmentStatusSubmitted, + }, + }, + }, nil) + + appCtx := suite.AppContextForTest() + eTag := etag.GenerateEtag(shipment.UpdatedAt) + + updatedShipment, err := updater.UpdateMTOShipmentStatus(appCtx, shipment.ID, models.MTOShipmentStatusApproved, nil, nil, eTag) + suite.NoError(err) + + serviceItems := models.MTOServiceItems{} + err = appCtx.DB().EagerPreload("ReService").Where("mto_shipment_id = ?", updatedShipment.ID).All(&serviceItems) + suite.NoError(err) + + for i := 0; i < len(expectedReServiceCodes); i++ { + suite.Equal(expectedReServiceCodes[i], serviceItems[i].ReService.Code) + } + }) +} diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index d52d7388ec4..5e05cec2f2f 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -2,6 +2,7 @@ package mtoshipment import ( "math" + "slices" "github.com/gofrs/uuid" "github.com/pkg/errors" @@ -77,14 +78,18 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen } } - // create international shipment service items - if shipment.ShipmentType == models.MTOShipmentTypeHHG && shipment.MarketCode == models.MarketCodeInternational { - err := models.CreateApprovedServiceItemsForShipment(appCtx.DB(), shipment) - if err != nil { - return shipment, err - } - } transactionError := appCtx.NewTransaction(func(txnAppCtx appcontext.AppContext) error { + + // If there are existing 're_service_items' for the international shipment then create 'mto_service_items' + // These are currently the shipment types we handle but add any additional international shipment types here + internationalShipmentTypes := []models.MTOShipmentType{models.MTOShipmentTypeHHG, models.MTOShipmentTypeHHGIntoNTS} + if slices.Contains(internationalShipmentTypes, shipment.ShipmentType) && shipment.MarketCode == models.MarketCodeInternational { + err := models.CreateApprovedServiceItemsForShipment(appCtx.DB(), shipment) + if err != nil { + return err + } + } + verrs, err := txnAppCtx.DB().ValidateAndSave(shipment) if verrs != nil && verrs.HasAny() { invalidInputError := apperror.NewInvalidInputError(shipment.ID, nil, verrs, "There was an issue with validating the updates") diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 3c1d36a4795..7033031584f 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -190,7 +190,7 @@ func (suite *MTOShipmentServiceSuite) createApproveShipmentSubtestData() (subtes } func (suite *MTOShipmentServiceSuite) TestApproveShipment() { - suite.Run("If the international mtoShipment is approved successfully it should create pre approved mtoServiceItems", func() { + suite.Run("Given international mtoShipment is approved successfully pre-approved mtoServiceItems are created HHG", func() { internationalShipment := factory.BuildMTOShipment(suite.AppContextForTest().DB(), []factory.Customization{ { Model: models.Move{ @@ -209,7 +209,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { }, { Model: models.MTOShipment{ - MarketCode: "i", + MarketCode: models.MarketCodeInternational, Status: models.MTOShipmentStatusSubmitted, }, }, @@ -255,6 +255,84 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { } }) + suite.Run("Given international mtoShipment is approved successfully pre-approved mtoServiceItems are created NTS", func() { + storageFacility := factory.BuildStorageFacility(suite.DB(), []factory.Customization{ + { + Model: models.StorageFacility{ + FacilityName: *models.StringPointer("Test Storage Name"), + Email: models.StringPointer("old@email.com"), + LotNumber: models.StringPointer("Test lot number"), + Phone: models.StringPointer("555-555-5555"), + }, + }, + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99507", + IsOconus: models.BoolPointer(true), + }, + }, + }, nil) + + internationalShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + }, + }, + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + }, + Type: &factory.Addresses.PickupAddress, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + Status: models.MTOShipmentStatusSubmitted, + ShipmentType: models.MTOShipmentTypeHHGIntoNTS, + }, + }, + { + Model: storageFacility, + LinkOnly: true, + }, + }, nil) + internationalShipmentEtag := etag.GenerateEtag(internationalShipment.UpdatedAt) + + shipmentRouter := NewShipmentRouter() + var serviceItemCreator services.MTOServiceItemCreator + var planner route.Planner + var moveWeights services.MoveWeights + + // Approve international shipment + shipmentApprover := NewShipmentApprover(shipmentRouter, serviceItemCreator, planner, moveWeights) + _, err := shipmentApprover.ApproveShipment(suite.AppContextForTest(), internationalShipment.ID, internationalShipmentEtag) + suite.NoError(err) + + // Get created pre approved service items + var serviceItems []models.MTOServiceItem + err2 := suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", internationalShipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err2) + + expectedReserviceCodes := []models.ReServiceCode{ + models.ReServiceCodeISLH, + models.ReServiceCodeINPK, + } + + suite.Equal(len(expectedReserviceCodes), len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + actualReServiceCode := serviceItems[i].ReService.Code + suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) + } + }) + suite.Run("If the mtoShipment is approved successfully it should create approved mtoServiceItems", func() { subtestData := suite.createApproveShipmentSubtestData() appCtx := subtestData.appCtx @@ -787,4 +865,25 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { suite.NotNil(shipment.MoveTaskOrder.ExcessWeightQualifiedAt) }) + + suite.Run("Given invalid shipment error returned", func() { + invalidShipment := factory.BuildMTOShipment(suite.AppContextForTest().DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + ShipmentType: models.MTOShipmentTypePPM, + }, + }, + }, nil) + invalidShipmentEtag := etag.GenerateEtag(invalidShipment.UpdatedAt) + + shipmentRouter := NewShipmentRouter() + var serviceItemCreator services.MTOServiceItemCreator + var planner route.Planner + var moveWeights services.MoveWeights + + // Approve international shipment + shipmentApprover := NewShipmentApprover(shipmentRouter, serviceItemCreator, planner, moveWeights) + _, err := shipmentApprover.ApproveShipment(suite.AppContextForTest(), invalidShipment.ID, invalidShipmentEtag) + suite.Error(err) + }) } From 03eb1289f1473693074899640838d88c788317e2 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Thu, 19 Dec 2024 14:17:53 +0000 Subject: [PATCH 02/10] adding comments for re_services --- ...620_add_international_nts_service_items.up.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql b/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql index 2bb5207813f..207c5379080 100644 --- a/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql +++ b/migrations/app/schema/20241218204620_add_international_nts_service_items.up.sql @@ -4,18 +4,33 @@ INSERT INTO re_service_items (id, service_id, shipment_type, market_code, is_auto_approved, created_at, updated_at, sort) VALUES + --ISLH International Shipping & Linehaul ('2a560507-db09-4be1-b809-49c0f515b31b', '9f3d551a-0725-430e-897e-80ee9add3ae9' ,'HHG_INTO_NTS', 'i', true, now(), now(), 1), + --PODFSC International POD Fuel Surcharge ('e702818f-defd-452c-81a3-865b902e7dd0', '388115e8-abe9-441d-96cf-a39f24baa0a3' ,'HHG_INTO_NTS', 'i', true, now(), now(), 2), + --INPK International NTS packing ('366ee5a4-eb61-4ded-a68c-ddc29fe1a886', '874cb86a-bc39-4f57-a614-53ee3fcacf14' ,'HHG_INTO_NTS', 'i', true, now(), now(), 3), + --ICRT International crating ('aac4e95e-27ed-4f09-9b6b-384d8542f410', '86203d72-7f7c-49ff-82f0-5b95e4958f60' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IDASIT International destination add'l day SIT ('010f2f91-7381-4149-8d74-8eb5f593a864', '806c6d59-57ff-4a3f-9518-ebf29ba9cb10' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IDDSIT International destination SIT delivery ('a41966b7-b83a-4eaf-8e68-d5e884777102', '28389ee1-56cf-400c-aa52-1501ecdd7c69' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IDFSIT International destination 1st day SIT ('14c77957-3c76-465a-bb07-c98d36ef1e54', 'bd6064ca-e780-4ab4-a37b-0ae98eebb244' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IDSHUT International destination shuttle service ('d52d2d03-100a-4ed9-b2de-16eac63a375f', '22fc07ed-be15-4f50-b941-cbd38153b378' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IOASIT International origin add'l day SIT ('7fd91408-7d69-4375-b7e6-5b2ff714206b', 'bd424e45-397b-4766-9712-de4ae3a2da36' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IOFSIT International origin 1st day SIT ('b3dc509d-d652-4300-a702-a1ddce6255b6', 'b488bf85-ea5e-49c8-ba5c-e2fa278ac806' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IOPSIT International origin SIT pickup ('001eadb6-3526-45b9-96e0-0648bb481e86', '6f4f6e31-0675-4051-b659-89832259f390' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IOSHUT International origin shuttle service ('b991c5c9-af2c-4146-b999-1d0bdf91de3f', '624a97c5-dfbf-4da9-a6e9-526b4f95af8d' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IUCRT International uncrating ('5a89315a-257b-4ef0-92cb-4c06aa6f1332', '4132416b-b1aa-42e7-98f2-0ac0a03e8a31' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IOFSC International Origin SIT Fuel Surcharge ('d4a98dea-a5f7-4b92-b5de-e6350ab07824', '81e29d0c-02a6-4a7a-be02-554deb3ee49e' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL), + --IDSFSC International Destination SIT Fuel Surcharge ('eaea90c2-93d3-4db9-89cd-23ac57ec9ce1', '690a5fc1-0ea5-4554-8294-a367b5daefa9' ,'HHG_INTO_NTS', 'i', false, now(), now(), NULL); From 2dd1c152386bbc5aed3562016a4d186e57c3cbc4 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Fri, 20 Dec 2024 15:36:59 +0000 Subject: [PATCH 03/10] added test --- .../mto_shipment/shipment_approver_test.go | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 7033031584f..3a0b923c30c 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -255,7 +255,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { } }) - suite.Run("Given international mtoShipment is approved successfully pre-approved mtoServiceItems are created NTS", func() { + suite.Run("Given international mtoShipment is approved successfully pre-approved mtoServiceItems are created NTS CONUS to OCONUS", func() { storageFacility := factory.BuildStorageFacility(suite.DB(), []factory.Customization{ { Model: models.StorageFacility{ @@ -333,6 +333,85 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { } }) + suite.Run("Given international mtoShipment is approved successfully pre-approved mtoServiceItems are created NTS OCONUS to CONUS", func() { + storageFacility := factory.BuildStorageFacility(suite.DB(), []factory.Customization{ + { + Model: models.StorageFacility{ + FacilityName: *models.StringPointer("Test Storage Name"), + Email: models.StringPointer("old@email.com"), + LotNumber: models.StringPointer("Test lot number"), + Phone: models.StringPointer("555-555-5555"), + }, + }, + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + }, + }, + }, nil) + + internationalShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVED, + }, + }, + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99507", + IsOconus: models.BoolPointer(true), + }, + Type: &factory.Addresses.PickupAddress, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + Status: models.MTOShipmentStatusSubmitted, + ShipmentType: models.MTOShipmentTypeHHGIntoNTS, + }, + }, + { + Model: storageFacility, + LinkOnly: true, + }, + }, nil) + internationalShipmentEtag := etag.GenerateEtag(internationalShipment.UpdatedAt) + + shipmentRouter := NewShipmentRouter() + var serviceItemCreator services.MTOServiceItemCreator + var planner route.Planner + var moveWeights services.MoveWeights + + // Approve international shipment + shipmentApprover := NewShipmentApprover(shipmentRouter, serviceItemCreator, planner, moveWeights) + _, err := shipmentApprover.ApproveShipment(suite.AppContextForTest(), internationalShipment.ID, internationalShipmentEtag) + suite.NoError(err) + + // Get created pre approved service items + var serviceItems []models.MTOServiceItem + err2 := suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", internationalShipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err2) + + expectedReserviceCodes := []models.ReServiceCode{ + models.ReServiceCodeISLH, + models.ReServiceCodePODFSC, + models.ReServiceCodeINPK, + } + + suite.Equal(len(expectedReserviceCodes), len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + actualReServiceCode := serviceItems[i].ReService.Code + suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) + } + }) + suite.Run("If the mtoShipment is approved successfully it should create approved mtoServiceItems", func() { subtestData := suite.createApproveShipmentSubtestData() appCtx := subtestData.appCtx From 08332c37dd86545576eefa45e2631af81de03558 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Fri, 20 Dec 2024 15:43:10 +0000 Subject: [PATCH 04/10] fixed asserts --- pkg/services/mto_shipment/shipment_approver_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 3a0b923c30c..f79f81677a3 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -323,6 +323,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { expectedReserviceCodes := []models.ReServiceCode{ models.ReServiceCodeISLH, + models.ReServiceCodePODFSC, models.ReServiceCodeINPK, } @@ -401,7 +402,6 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { expectedReserviceCodes := []models.ReServiceCode{ models.ReServiceCodeISLH, - models.ReServiceCodePODFSC, models.ReServiceCodeINPK, } From 0efdd5421799b474c42501bc9277b07f3a138c1e Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Fri, 20 Dec 2024 16:08:35 +0000 Subject: [PATCH 05/10] should be it --- pkg/services/mto_shipment/shipment_approver_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index f79f81677a3..3a0b923c30c 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -323,7 +323,6 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { expectedReserviceCodes := []models.ReServiceCode{ models.ReServiceCodeISLH, - models.ReServiceCodePODFSC, models.ReServiceCodeINPK, } @@ -402,6 +401,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { expectedReserviceCodes := []models.ReServiceCode{ models.ReServiceCodeISLH, + models.ReServiceCodePODFSC, models.ReServiceCodeINPK, } From 6449f4d8fa01c7d5b850b53a347b736b597901a8 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Tue, 7 Jan 2025 16:22:00 +0000 Subject: [PATCH 06/10] maybe fix factory for oconus to conus --- pkg/factory/mto_shipment_factory.go | 6 +++++- pkg/services/mto_shipment/shipment_approver_test.go | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/factory/mto_shipment_factory.go b/pkg/factory/mto_shipment_factory.go index 1c7858d572f..025a94fc09c 100644 --- a/pkg/factory/mto_shipment_factory.go +++ b/pkg/factory/mto_shipment_factory.go @@ -57,7 +57,7 @@ func buildMTOShipmentWithBuildType(db *pop.Connection, customs []Customization, defaultStatus = models.MTOShipmentStatusDraft buildStorageFacility = hasStorageFacilityCustom shipmentHasPickupDetails = true - shipmentHasDeliveryDetails = false + shipmentHasDeliveryDetails = true case mtoShipmentNTSR: defaultShipmentType = models.MTOShipmentTypeHHGOutOfNTSDom defaultStatus = models.MTOShipmentStatusDraft @@ -83,6 +83,10 @@ func buildMTOShipmentWithBuildType(db *pop.Connection, customs []Customization, MarketCode: defaultMarketCode, } + if newMTOShipment.ShipmentType == models.MTOShipmentTypeHHGIntoNTS && newMTOShipment.StorageFacility != nil { + newMTOShipment.DestinationAddress = &newMTOShipment.StorageFacility.Address + } + if cMtoShipment.Status == models.MTOShipmentStatusApproved { approvedDate := time.Date(GHCTestYear, time.March, 20, 0, 0, 0, 0, time.UTC) newMTOShipment.ApprovedDate = &approvedDate diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 3a0b923c30c..3ecbc0a203f 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -354,7 +354,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { }, }, nil) - internationalShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + internationalShipment := factory.BuildNTSShipment(suite.DB(), []factory.Customization{ { Model: models.Move{ Status: models.MoveStatusAPPROVED, From b5e5c229128fb3a7d3ba3b4f929febfc1b08f266 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Tue, 7 Jan 2025 16:56:58 +0000 Subject: [PATCH 07/10] update factory test --- pkg/factory/mto_shipment_factory_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/factory/mto_shipment_factory_test.go b/pkg/factory/mto_shipment_factory_test.go index ea43a0a0373..60403a50f0d 100644 --- a/pkg/factory/mto_shipment_factory_test.go +++ b/pkg/factory/mto_shipment_factory_test.go @@ -450,9 +450,9 @@ func (suite *FactorySuite) TestBuildMTOShipment() { suite.NotNil(ntsShipment.PrimeActualWeight) suite.Nil(ntsShipment.StorageFacility) suite.NotNil(ntsShipment.ScheduledPickupDate) - suite.Nil(ntsShipment.RequestedDeliveryDate) + suite.NotNil(ntsShipment.RequestedDeliveryDate) suite.Nil(ntsShipment.ActualDeliveryDate) - suite.Nil(ntsShipment.ScheduledDeliveryDate) + suite.NotNil(ntsShipment.ScheduledDeliveryDate) }) suite.Run("Successful creation of NTSShipment with storage facility", func() { From df504787473a05c8b362a3eca4ff92d88dd7e22d Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Thu, 16 Jan 2025 16:37:47 +0000 Subject: [PATCH 08/10] adding missing changes to updater --- .../mto_shipment/mto_shipment_updater.go | 86 +++++++++---------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index d1367ebef05..4da7227e596 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -855,8 +855,8 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, // we will compare data here to see if we even need to update the pricing if newShipment.MarketCode == models.MarketCodeInternational && (newShipment.PrimeEstimatedWeight != nil || - newShipment.PickupAddress != nil && newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || - newShipment.DestinationAddress != nil && newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || + newShipment.PickupAddress != nil && dbShipment.PickupAddress != nil && newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || + newShipment.DestinationAddress != nil && dbShipment.DestinationAddress != nil && newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || newShipment.RequestedPickupDate != nil && newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { portZip, portType, err := models.GetPortLocationInfoForShipment(appCtx.DB(), newShipment.ID) @@ -1110,9 +1110,9 @@ func reServiceCodesForShipment(shipment models.MTOShipment) []models.ReServiceCo // More info in MB-1140: https://dp3.atlassian.net/browse/MB-1140 // international shipment service items are created in the shipment_approver - switch shipment.ShipmentType { - case models.MTOShipmentTypeHHG: - if shipment.MarketCode != models.MarketCodeInternational { + if shipment.MarketCode != models.MarketCodeInternational { + switch shipment.ShipmentType { + case models.MTOShipmentTypeHHG: originZIP3 := shipment.PickupAddress.PostalCode[0:3] destinationZIP3 := shipment.DestinationAddress.PostalCode[0:3] @@ -1136,9 +1136,7 @@ func reServiceCodesForShipment(shipment models.MTOShipment) []models.ReServiceCo models.ReServiceCodeDPK, models.ReServiceCodeDUPK, } - } - case models.MTOShipmentTypeHHGIntoNTS: - if shipment.MarketCode != models.MarketCodeInternational { + case models.MTOShipmentTypeHHGIntoNTS: // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom NTS Packing return []models.ReServiceCode{ models.ReServiceCodeDLH, @@ -1147,42 +1145,42 @@ func reServiceCodesForShipment(shipment models.MTOShipment) []models.ReServiceCo models.ReServiceCodeDDP, models.ReServiceCodeDNPK, } - } - case models.MTOShipmentTypeHHGOutOfNTSDom: - // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Unpacking - return []models.ReServiceCode{ - models.ReServiceCodeDLH, - models.ReServiceCodeFSC, - models.ReServiceCodeDOP, - models.ReServiceCodeDDP, - models.ReServiceCodeDUPK, - } - case models.MTOShipmentTypeMobileHome: - // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Mobile Home Factor - return []models.ReServiceCode{ - models.ReServiceCodeDLH, - models.ReServiceCodeFSC, - models.ReServiceCodeDOP, - models.ReServiceCodeDDP, - models.ReServiceCodeDMHF, - } - case models.MTOShipmentTypeBoatHaulAway: - // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Haul Away Boat Factor - return []models.ReServiceCode{ - models.ReServiceCodeDLH, - models.ReServiceCodeFSC, - models.ReServiceCodeDOP, - models.ReServiceCodeDDP, - models.ReServiceCodeDBHF, - } - case models.MTOShipmentTypeBoatTowAway: - // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Tow Away Boat Factor - return []models.ReServiceCode{ - models.ReServiceCodeDLH, - models.ReServiceCodeFSC, - models.ReServiceCodeDOP, - models.ReServiceCodeDDP, - models.ReServiceCodeDBTF, + case models.MTOShipmentTypeHHGOutOfNTSDom: + // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Unpacking + return []models.ReServiceCode{ + models.ReServiceCodeDLH, + models.ReServiceCodeFSC, + models.ReServiceCodeDOP, + models.ReServiceCodeDDP, + models.ReServiceCodeDUPK, + } + case models.MTOShipmentTypeMobileHome: + // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Mobile Home Factor + return []models.ReServiceCode{ + models.ReServiceCodeDLH, + models.ReServiceCodeFSC, + models.ReServiceCodeDOP, + models.ReServiceCodeDDP, + models.ReServiceCodeDMHF, + } + case models.MTOShipmentTypeBoatHaulAway: + // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Haul Away Boat Factor + return []models.ReServiceCode{ + models.ReServiceCodeDLH, + models.ReServiceCodeFSC, + models.ReServiceCodeDOP, + models.ReServiceCodeDDP, + models.ReServiceCodeDBHF, + } + case models.MTOShipmentTypeBoatTowAway: + // Need to create: Dom Linehaul, Fuel Surcharge, Dom Origin Price, Dom Destination Price, Dom Tow Away Boat Factor + return []models.ReServiceCode{ + models.ReServiceCodeDLH, + models.ReServiceCodeFSC, + models.ReServiceCodeDOP, + models.ReServiceCodeDDP, + models.ReServiceCodeDBTF, + } } } From c44931c3ff328db1f53c444240c955edb5017cfe Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Thu, 16 Jan 2025 16:41:40 +0000 Subject: [PATCH 09/10] adding missing change from test --- pkg/services/mto_shipment/shipment_approver_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index c5488cdc14f..f99b01adc07 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -294,9 +294,10 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { suite.NoError(err2) expectedReserviceCodes := []models.ReServiceCode{ + models.ReServiceCodePOEFSC, models.ReServiceCodeISLH, - models.ReServiceCodePODFSC, - models.ReServiceCodeINPK, + models.ReServiceCodeIHPK, + models.ReServiceCodeIHUPK, } suite.Equal(len(expectedReserviceCodes), len(serviceItems)) From f55128054d4723bf52599702db0f9c1da4a66374 Mon Sep 17 00:00:00 2001 From: KonstanceH Date: Thu, 16 Jan 2025 17:51:29 +0000 Subject: [PATCH 10/10] adding missing from test --- pkg/services/mto_shipment/mto_shipment_updater_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 6f9620ed147..63d4af96dc8 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -3461,10 +3461,6 @@ func (suite *MTOShipmentServiceSuite) TestUpdateDomesticServiceItems() { var mto models.Move setupTestData := func() { - for i := range expectedReServiceCodes { - factory.FetchReServiceByCode(suite.DB(), expectedReServiceCodes[i]) - } - pickupAddress = factory.BuildAddress(suite.DB(), []factory.Customization{ { Model: models.Address{