diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index e1e9c8a7b75..0b93e1484c1 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -83,9 +83,22 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { signedCertificationCreator := signedcertification.NewSignedCertificationCreator() signedCertificationUpdater := signedcertification.NewSignedCertificationUpdater() ppmEstimator := ppmshipment.NewEstimatePPM(handlerConfig.DTODPlanner(), &paymentrequesthelper.RequestPaymentHelper{}) + + mtoServiceItemCreator := mtoserviceitem.NewMTOServiceItemCreator( + handlerConfig.HHGPlanner(), + queryBuilder, + moveRouter, + ghcrateengine.NewDomesticUnpackPricer(), + ghcrateengine.NewDomesticPackPricer(), + ghcrateengine.NewDomesticLinehaulPricer(), + ghcrateengine.NewDomesticShorthaulPricer(), + ghcrateengine.NewDomesticOriginPricer(), + ghcrateengine.NewDomesticDestinationPricer(), + ghcrateengine.NewFuelSurchargePricer()) + moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( queryBuilder, - mtoserviceitem.NewMTOServiceItemCreator(handlerConfig.HHGPlanner(), queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()), + mtoServiceItemCreator, moveRouter, signedCertificationCreator, signedCertificationUpdater, ppmEstimator, ) @@ -234,7 +247,7 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { paymentRequestShipmentRecalculator, addressUpdater, addressCreator) - sitExtensionShipmentUpdater := shipment.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + sitExtensionShipmentUpdater := shipment.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) ghcAPI.MtoServiceItemUpdateServiceItemSitEntryDateHandler = UpdateServiceItemSitEntryDateHandler{ HandlerConfig: handlerConfig, @@ -428,7 +441,7 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { handlerConfig, mtoshipment.NewShipmentApprover( mtoshipment.NewShipmentRouter(), - mtoserviceitem.NewMTOServiceItemCreator(handlerConfig.HHGPlanner(), queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()), + mtoServiceItemCreator, handlerConfig.HHGPlanner(), move.NewMoveWeights(mtoshipment.NewShipmentReweighRequester(), waf), moveTaskOrderUpdater, @@ -499,7 +512,7 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { addressCreator, ) - shipmentUpdater := shipment.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipment.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) ghcAPI.MoveSearchMovesHandler = SearchMovesHandler{ HandlerConfig: handlerConfig, diff --git a/pkg/handlers/ghcapi/mto_service_items_test.go b/pkg/handlers/ghcapi/mto_service_items_test.go index a380a72356e..40623c26004 100644 --- a/pkg/handlers/ghcapi/mto_service_items_test.go +++ b/pkg/handlers/ghcapi/mto_service_items_test.go @@ -425,7 +425,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { ppmShipmentUpdater := ppmshipment.NewPPMShipmentUpdater(&ppmEstimator, addressCreator, addressUpdater) boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) shipmentFetcher := mtoshipment.NewMTOShipmentFetcher() moveTaskOrderID, _ := uuid.NewV4() @@ -877,7 +877,7 @@ func (suite *HandlerSuite) TestUpdateServiceItemSitEntryDateHandler() { ppmShipmentUpdater := ppmshipment.NewPPMShipmentUpdater(&ppmEstimator, addressCreator, addressUpdater) boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) shipmentFetcher := mtoshipment.NewMTOShipmentFetcher() suite.Run("200 - success response", func() { diff --git a/pkg/handlers/ghcapi/mto_shipment_test.go b/pkg/handlers/ghcapi/mto_shipment_test.go index 70ac78cbaac..3b769d41d17 100644 --- a/pkg/handlers/ghcapi/mto_shipment_test.go +++ b/pkg/handlers/ghcapi/mto_shipment_test.go @@ -3293,7 +3293,7 @@ func (suite *HandlerSuite) TestApproveSITExtensionHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - sitExtensionShipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + sitExtensionShipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := ApproveSITExtensionHandler{ handlerConfig, @@ -3437,7 +3437,7 @@ func (suite *HandlerSuite) CreateApprovedSITDurationUpdate() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - sitExtensionShipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + sitExtensionShipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := CreateApprovedSITDurationUpdateHandler{ handlerConfig, @@ -3523,7 +3523,7 @@ func (suite *HandlerSuite) CreateApprovedSITDurationUpdate() { mobilehomeshipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - sitExtensionShipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobilehomeshipmentUpdater) + sitExtensionShipmentUpdater := shipmentorchestrator.NewShipmentUpdater(noCheckUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobilehomeshipmentUpdater, nil) handler := CreateApprovedSITDurationUpdateHandler{ handlerConfig, @@ -4593,7 +4593,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { ppmShipmentUpdater := ppmshipment.NewPPMShipmentUpdater(&ppmEstimator, addressCreator, addressUpdater) boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -4661,7 +4661,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -4847,7 +4847,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -4927,7 +4927,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -5007,7 +5007,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -5045,7 +5045,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -5085,7 +5085,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, @@ -5126,7 +5126,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) handler := UpdateShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, diff --git a/pkg/handlers/internalapi/api.go b/pkg/handlers/internalapi/api.go index cbdba27433a..31010c7e3da 100644 --- a/pkg/handlers/internalapi/api.go +++ b/pkg/handlers/internalapi/api.go @@ -193,11 +193,23 @@ func NewInternalAPI(handlerConfig handlers.HandlerConfig) *internalops.MymoveAPI postalcodeservice.NewPostalCodeValidator(clock.New()), } + mtoServiceItemCreator := mtoserviceitem.NewMTOServiceItemCreator( + handlerConfig.HHGPlanner(), + builder, + moveRouter, + ghcrateengine.NewDomesticUnpackPricer(), + ghcrateengine.NewDomesticPackPricer(), + ghcrateengine.NewDomesticLinehaulPricer(), + ghcrateengine.NewDomesticShorthaulPricer(), + ghcrateengine.NewDomesticOriginPricer(), + ghcrateengine.NewDomesticDestinationPricer(), + ghcrateengine.NewFuelSurchargePricer()) + mtoShipmentCreator := mtoshipment.NewMTOShipmentCreatorV1(builder, fetcher, moveRouter, addressCreator) shipmentRouter := mtoshipment.NewShipmentRouter() moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, - mtoserviceitem.NewMTOServiceItemCreator(handlerConfig.HHGPlanner(), builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()), + mtoServiceItemCreator, moveRouter, signedCertificationCreator, signedCertificationUpdater, ppmEstimator, ) boatShipmentCreator := boatshipment.NewBoatShipmentCreator() @@ -233,6 +245,7 @@ func NewInternalAPI(handlerConfig handlers.HandlerConfig) *internalops.MymoveAPI ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, + mtoServiceItemCreator, ) internalAPI.MtoShipmentUpdateMTOShipmentHandler = UpdateMTOShipmentHandler{ diff --git a/pkg/handlers/internalapi/mto_shipment_test.go b/pkg/handlers/internalapi/mto_shipment_test.go index bdd7770f408..2a06643c691 100644 --- a/pkg/handlers/internalapi/mto_shipment_test.go +++ b/pkg/handlers/internalapi/mto_shipment_test.go @@ -763,7 +763,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, nil) authRequestAndSetUpHandlerAndParams := func(originalShipment models.MTOShipment, mockShipmentUpdater *mocks.ShipmentUpdater) (UpdateMTOShipmentHandler, mtoshipmentops.UpdateMTOShipmentParams) { endpoint := fmt.Sprintf("/mto-shipments/%s", originalShipment.ID.String()) diff --git a/pkg/handlers/primeapiv2/api.go b/pkg/handlers/primeapiv2/api.go index 2d22387e986..44e8ca916ef 100644 --- a/pkg/handlers/primeapiv2/api.go +++ b/pkg/handlers/primeapiv2/api.go @@ -53,9 +53,21 @@ func NewPrimeAPI(handlerConfig handlers.HandlerConfig) *primev2operations.Mymove signedCertificationUpdater := signedcertification.NewSignedCertificationUpdater() ppmEstimator := ppmshipment.NewEstimatePPM(handlerConfig.DTODPlanner(), &paymentrequesthelper.RequestPaymentHelper{}) + mtoServiceItemCreator := mtoserviceitem.NewMTOServiceItemCreator( + handlerConfig.HHGPlanner(), + queryBuilder, + moveRouter, + ghcrateengine.NewDomesticUnpackPricer(), + ghcrateengine.NewDomesticPackPricer(), + ghcrateengine.NewDomesticLinehaulPricer(), + ghcrateengine.NewDomesticShorthaulPricer(), + ghcrateengine.NewDomesticOriginPricer(), + ghcrateengine.NewDomesticDestinationPricer(), + ghcrateengine.NewFuelSurchargePricer()) + moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( queryBuilder, - mtoserviceitem.NewMTOServiceItemCreator(handlerConfig.HHGPlanner(), queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()), + mtoServiceItemCreator, moveRouter, signedCertificationCreator, signedCertificationUpdater, ppmEstimator, ) @@ -97,10 +109,11 @@ func NewPrimeAPI(handlerConfig handlers.HandlerConfig) *primev2operations.Mymove ppmShipmentUpdater := ppmshipment.NewPPMShipmentUpdater(ppmEstimator, addressCreator, addressUpdater) boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipment.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipment.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) primeAPIV2.MtoShipmentUpdateMTOShipmentHandler = UpdateMTOShipmentHandler{ handlerConfig, shipmentUpdater, + handlerConfig.DTODPlanner(), } return primeAPIV2 diff --git a/pkg/handlers/primeapiv2/mto_shipment.go b/pkg/handlers/primeapiv2/mto_shipment.go index 35672bbc02e..d4a5e5012da 100644 --- a/pkg/handlers/primeapiv2/mto_shipment.go +++ b/pkg/handlers/primeapiv2/mto_shipment.go @@ -17,6 +17,7 @@ import ( "github.com/transcom/mymove/pkg/handlers/primeapi" "github.com/transcom/mymove/pkg/handlers/primeapiv2/payloads" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/route" "github.com/transcom/mymove/pkg/services" mtoshipment "github.com/transcom/mymove/pkg/services/mto_shipment" ) @@ -169,6 +170,7 @@ func (h CreateMTOShipmentHandler) Handle(params mtoshipmentops.CreateMTOShipment type UpdateMTOShipmentHandler struct { handlers.HandlerConfig services.ShipmentUpdater + planner route.Planner } // Handle handler that updates a mto shipment diff --git a/pkg/handlers/primeapiv3/api.go b/pkg/handlers/primeapiv3/api.go index 1662d151464..e46f49c8ad1 100644 --- a/pkg/handlers/primeapiv3/api.go +++ b/pkg/handlers/primeapiv3/api.go @@ -95,13 +95,26 @@ func NewPrimeAPI(handlerConfig handlers.HandlerConfig) *primev3operations.Mymove addressCreator, ) + mtoServiceItemCreator := mtoserviceitem.NewMTOServiceItemCreator( + handlerConfig.HHGPlanner(), + queryBuilder, + moveRouter, + ghcrateengine.NewDomesticUnpackPricer(), + ghcrateengine.NewDomesticPackPricer(), + ghcrateengine.NewDomesticLinehaulPricer(), + ghcrateengine.NewDomesticShorthaulPricer(), + ghcrateengine.NewDomesticOriginPricer(), + ghcrateengine.NewDomesticDestinationPricer(), + ghcrateengine.NewFuelSurchargePricer()) + ppmShipmentUpdater := ppmshipment.NewPPMShipmentUpdater(ppmEstimator, addressCreator, addressUpdater) boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() - shipmentUpdater := shipment.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipment.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) primeAPIV3.MtoShipmentUpdateMTOShipmentHandler = UpdateMTOShipmentHandler{ handlerConfig, shipmentUpdater, + handlerConfig.DTODPlanner(), } return primeAPIV3 diff --git a/pkg/handlers/primeapiv3/mto_shipment.go b/pkg/handlers/primeapiv3/mto_shipment.go index cddeeaab45b..d2f6221ac9f 100644 --- a/pkg/handlers/primeapiv3/mto_shipment.go +++ b/pkg/handlers/primeapiv3/mto_shipment.go @@ -17,6 +17,7 @@ import ( "github.com/transcom/mymove/pkg/handlers/primeapi" "github.com/transcom/mymove/pkg/handlers/primeapiv3/payloads" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/route" "github.com/transcom/mymove/pkg/services" mtoshipment "github.com/transcom/mymove/pkg/services/mto_shipment" ) @@ -169,6 +170,7 @@ func (h CreateMTOShipmentHandler) Handle(params mtoshipmentops.CreateMTOShipment type UpdateMTOShipmentHandler struct { handlers.HandlerConfig services.ShipmentUpdater + planner route.Planner } // Handle handler that updates a mto shipment diff --git a/pkg/handlers/primeapiv3/mto_shipment_test.go b/pkg/handlers/primeapiv3/mto_shipment_test.go index 8bcef3ec944..085d9eab254 100644 --- a/pkg/handlers/primeapiv3/mto_shipment_test.go +++ b/pkg/handlers/primeapiv3/mto_shipment_test.go @@ -86,10 +86,10 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { return mockUpdater } - + mtoServiceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, - mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()), + mtoServiceItemCreator, moveRouter, setUpSignedCertificationCreatorMock(nil, nil), setUpSignedCertificationUpdaterMock(nil, nil), &ppmEstimator, ) shipmentCreator := shipmentorchestrator.NewShipmentCreator(mtoShipmentCreator, ppmShipmentCreator, boatShipmentCreator, mobileHomeShipmentCreator, shipmentRouter, moveTaskOrderUpdater) @@ -112,7 +112,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { boatShipmentUpdater := boatshipment.NewBoatShipmentUpdater() mobileHomeShipmentUpdater := mobilehomeshipment.NewMobileHomeShipmentUpdater() mtoShipmentUpdater := mtoshipment.NewPrimeMTOShipmentUpdater(builder, fetcher, planner, moveRouter, moveWeights, suite.TestNotificationSender(), paymentRequestShipmentRecalculator, addressUpdater, addressCreator) - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) setupTestData := func(boatFeatureFlag bool, ubFeatureFlag bool) (CreateMTOShipmentHandler, models.Move) { @@ -551,6 +551,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { patchHandler := UpdateMTOShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, + planner, } patchReq := httptest.NewRequest("PATCH", fmt.Sprintf("/mto-shipments/%s", createdPPM.ShipmentID.String()), nil) @@ -832,6 +833,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { patchHandler := UpdateMTOShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, + planner, } patchReq := httptest.NewRequest("PATCH", fmt.Sprintf("/mto-shipments/%s", createdPPM.ShipmentID.String()), nil) @@ -1547,10 +1549,11 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { // Setup: If underlying CreateMTOShipment returns error, handler should return 422 response // Expected: 422 Response returned - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) patchHandler := UpdateMTOShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, + planner, } now := time.Now() @@ -1622,10 +1625,11 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { // Setup: If underlying UpdateMTOShipment returns error, handler should return 422 response // Expected: 422 Response returned - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) patchHandler := UpdateMTOShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, + planner, } move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{}, nil) @@ -1670,10 +1674,11 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { // Setup: If underlying CreateMTOShipment returns error, handler should return 422 response // Expected: 422 Response returned - shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater) + shipmentUpdater := shipmentorchestrator.NewShipmentUpdater(mtoShipmentUpdater, ppmShipmentUpdater, boatShipmentUpdater, mobileHomeShipmentUpdater, mtoServiceItemCreator) patchHandler := UpdateMTOShipmentHandler{ suite.HandlerConfig(), shipmentUpdater, + planner, } now := time.Now() diff --git a/pkg/services/mto_service_item/mto_service_item_creator.go b/pkg/services/mto_service_item/mto_service_item_creator.go index 7817accaf76..3b46e33ea3a 100644 --- a/pkg/services/mto_service_item/mto_service_item_creator.go +++ b/pkg/services/mto_service_item/mto_service_item_creator.go @@ -39,6 +39,7 @@ type mtoServiceItemCreator struct { fuelSurchargePricer services.FuelSurchargePricer } +// FindEstimatedPrice finds the estimated price for a service item func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, serviceItem *models.MTOServiceItem, mtoShipment models.MTOShipment) (unit.Cents, error) { if serviceItem.ReService.Code == models.ReServiceCodeDOP || serviceItem.ReService.Code == models.ReServiceCodeDPK || @@ -55,11 +56,8 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, requestedPickupDate := *mtoShipment.RequestedPickupDate currTime := time.Now() var distance int - primeEstimatedWeight := mtoShipment.PrimeEstimatedWeight - if mtoShipment.ShipmentType == models.MTOShipmentTypeHHGOutOfNTS { - newWeight := int(primeEstimatedWeight.Float64() * 1.1) - primeEstimatedWeight = (*unit.Pound)(&newWeight) - } + + adjustedWeight := GetAdjustedWeight(*mtoShipment.PrimeEstimatedWeight, mtoShipment.ShipmentType == models.MTOShipmentTypeUnaccompaniedBaggage) contractCode, err := FetchContractCode(appCtx, currTime) if err != nil { @@ -78,7 +76,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, return 0, err } - price, _, err = o.originPricer.Price(appCtx, contractCode, requestedPickupDate, *primeEstimatedWeight, domesticServiceArea.ServiceArea, isPPM) + price, _, err = o.originPricer.Price(appCtx, contractCode, requestedPickupDate, *adjustedWeight, domesticServiceArea.ServiceArea, isPPM) if err != nil { return 0, err } @@ -91,7 +89,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, servicesScheduleOrigin := domesticServiceArea.ServicesSchedule - price, _, err = o.packPricer.Price(appCtx, contractCode, requestedPickupDate, *primeEstimatedWeight, servicesScheduleOrigin, isPPM) + price, _, err = o.packPricer.Price(appCtx, contractCode, requestedPickupDate, *adjustedWeight, servicesScheduleOrigin, isPPM) if err != nil { return 0, err } @@ -106,7 +104,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, } } - price, _, err = o.destinationPricer.Price(appCtx, contractCode, requestedPickupDate, *primeEstimatedWeight, domesticServiceArea.ServiceArea, isPPM) + price, _, err = o.destinationPricer.Price(appCtx, contractCode, requestedPickupDate, *adjustedWeight, domesticServiceArea.ServiceArea, isPPM) if err != nil { return 0, err } @@ -119,7 +117,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, serviceScheduleDestination := domesticServiceArea.ServicesSchedule - price, _, err = o.unpackPricer.Price(appCtx, contractCode, requestedPickupDate, *primeEstimatedWeight, serviceScheduleDestination, isPPM) + price, _, err = o.unpackPricer.Price(appCtx, contractCode, requestedPickupDate, *adjustedWeight, serviceScheduleDestination, isPPM) if err != nil { return 0, err } @@ -137,7 +135,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, return 0, err } } - price, _, err = o.linehaulPricer.Price(appCtx, contractCode, requestedPickupDate, unit.Miles(distance), *primeEstimatedWeight, domesticServiceArea.ServiceArea, isPPM) + price, _, err = o.linehaulPricer.Price(appCtx, contractCode, requestedPickupDate, unit.Miles(distance), *adjustedWeight, domesticServiceArea.ServiceArea, isPPM) if err != nil { return 0, err } @@ -153,7 +151,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, return 0, err } } - price, _, err = o.shorthaulPricer.Price(appCtx, contractCode, requestedPickupDate, unit.Miles(distance), *primeEstimatedWeight, domesticServiceArea.ServiceArea) + price, _, err = o.shorthaulPricer.Price(appCtx, contractCode, requestedPickupDate, unit.Miles(distance), *adjustedWeight, domesticServiceArea.ServiceArea) if err != nil { return 0, err } @@ -177,7 +175,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, } } - fscWeightBasedDistanceMultiplier, err := LookupFSCWeightBasedDistanceMultiplier(appCtx, *primeEstimatedWeight) + fscWeightBasedDistanceMultiplier, err := LookupFSCWeightBasedDistanceMultiplier(appCtx, *adjustedWeight) if err != nil { return 0, err } @@ -189,7 +187,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, if err != nil { return 0, err } - price, _, err = o.fuelSurchargePricer.Price(appCtx, pickupDateForFSC, unit.Miles(distance), *primeEstimatedWeight, fscWeightBasedDistanceMultiplierFloat, eiaFuelPrice, isPPM) + price, _, err = o.fuelSurchargePricer.Price(appCtx, pickupDateForFSC, unit.Miles(distance), *adjustedWeight, fscWeightBasedDistanceMultiplierFloat, eiaFuelPrice, isPPM) if err != nil { return 0, err } @@ -608,6 +606,8 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex // if estimated weight for shipment provided by the prime, calculate the estimated prices for // DLH, DPK, DOP, DDP, DUPK + + // NTS-release requested pickup dates are for handle out, their pricing is handled differently as their locations are based on storage facilities, not pickup locations if mtoShipment.PrimeEstimatedWeight != nil && mtoShipment.RequestedPickupDate != nil { serviceItemEstimatedPrice, err := o.FindEstimatedPrice(appCtx, serviceItem, mtoShipment) if serviceItemEstimatedPrice != 0 && err == nil { @@ -954,3 +954,22 @@ func (o *mtoServiceItemCreator) validateFirstDaySITServiceItem(appCtx appcontext return &extraServiceItems, nil } + +// Get Adjusted weight for pricing. Returns the weight at 110% or the minimum billable weight whichever is higher, unless it's 0 +func GetAdjustedWeight(incomingWeight unit.Pound, isUB bool) *unit.Pound { + // minimum weight billed by GHC is 500 lbs unless it's Unaccompanied Baggage (UB) + minimumBilledWeight := unit.Pound(500) + if isUB { + minimumBilledWeight = unit.Pound(300) + } + + // add 110% modifier to billable weight + newWeight := (int(incomingWeight.Float64() * 1.1)) + adjustedWeight := (*unit.Pound)(&newWeight) + + // if the adjusted weight is less than the minimum billable weight but is nonzero, set it to the minimum weight billed + if *adjustedWeight < minimumBilledWeight && *adjustedWeight > 0 { + *adjustedWeight = minimumBilledWeight + } + return adjustedWeight +} diff --git a/pkg/services/mto_service_item/mto_service_item_creator_test.go b/pkg/services/mto_service_item/mto_service_item_creator_test.go index 3c35a91628a..9a9146f50d8 100644 --- a/pkg/services/mto_service_item/mto_service_item_creator_test.go +++ b/pkg/services/mto_service_item/mto_service_item_creator_test.go @@ -2108,22 +2108,22 @@ func (suite *MTOServiceItemServiceSuite) TestPriceEstimator() { creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) dopEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemDOP, shipment) - suite.Equal(unit.Cents(61080), dopEstimatedPriceInCents) + suite.Equal(unit.Cents(67188), dopEstimatedPriceInCents) dpkEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemDPK, shipment) - suite.Equal(unit.Cents(540000), dpkEstimatedPriceInCents) + suite.Equal(unit.Cents(594000), dpkEstimatedPriceInCents) ddpEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemDDP, shipment) - suite.Equal(unit.Cents(42240), ddpEstimatedPriceInCents) + suite.Equal(unit.Cents(46464), ddpEstimatedPriceInCents) dupkEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemDUPK, shipment) - suite.Equal(unit.Cents(43860), dupkEstimatedPriceInCents) + suite.Equal(unit.Cents(48246), dupkEstimatedPriceInCents) dlhEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemDLH, shipment) - suite.Equal(unit.Cents(12381600), dlhEstimatedPriceInCents) + suite.Equal(unit.Cents(13619760), dlhEstimatedPriceInCents) dshEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemDSH, shipment) - suite.Equal(unit.Cents(10080000), dshEstimatedPriceInCents) + suite.Equal(unit.Cents(11088000), dshEstimatedPriceInCents) fscEstimatedPriceInCents, _ := creator.FindEstimatedPrice(suite.AppContextForTest(), &serviceItemFSC, shipment) suite.Equal(unit.Cents(-168), fscEstimatedPriceInCents) @@ -2430,3 +2430,66 @@ func (suite *MTOServiceItemServiceSuite) TestPriceEstimator() { }) } +func (suite *MTOServiceItemServiceSuite) TestGetAdjustedWeight() { + suite.Run("If no weight is provided", func() { + var incomingWeight unit.Pound + adjustedWeight := GetAdjustedWeight(incomingWeight, false) + suite.Equal(unit.Pound(0), *adjustedWeight) + }) + suite.Run("If a weight of 0 is provided", func() { + incomingWeight := unit.Pound(0) + adjustedWeight := GetAdjustedWeight(incomingWeight, false) + suite.Equal(unit.Pound(0), *adjustedWeight) + }) + suite.Run("If weight of 100 is provided", func() { + incomingWeight := unit.Pound(100) + adjustedWeight := GetAdjustedWeight(incomingWeight, false) + suite.Equal(unit.Pound(500), *adjustedWeight) + }) + suite.Run("If weight of 454 is provided", func() { + incomingWeight := unit.Pound(454) + adjustedWeight := GetAdjustedWeight(incomingWeight, false) + suite.Equal(unit.Pound(500), *adjustedWeight) + }) + suite.Run("If weight of 456 is provided", func() { + incomingWeight := unit.Pound(456) + adjustedWeight := GetAdjustedWeight(incomingWeight, false) + suite.Equal(unit.Pound(501), *adjustedWeight) + }) + suite.Run("If weight of 1000 is provided", func() { + incomingWeight := unit.Pound(1000) + adjustedWeight := GetAdjustedWeight(incomingWeight, false) + suite.Equal(unit.Pound(1100), *adjustedWeight) + }) + + suite.Run("If no weight is provided UB", func() { + var incomingWeight unit.Pound + adjustedWeight := GetAdjustedWeight(incomingWeight, true) + suite.Equal(unit.Pound(0), *adjustedWeight) + }) + suite.Run("If a weight of 0 is provided UB", func() { + incomingWeight := unit.Pound(0) + adjustedWeight := GetAdjustedWeight(incomingWeight, true) + suite.Equal(unit.Pound(0), *adjustedWeight) + }) + suite.Run("If weight of 100 is provided UB", func() { + incomingWeight := unit.Pound(100) + adjustedWeight := GetAdjustedWeight(incomingWeight, true) + suite.Equal(unit.Pound(300), *adjustedWeight) + }) + suite.Run("If weight of 272 is provided UB", func() { + incomingWeight := unit.Pound(272) + adjustedWeight := GetAdjustedWeight(incomingWeight, true) + suite.Equal(unit.Pound(300), *adjustedWeight) + }) + suite.Run("If weight of 274 is provided UB", func() { + incomingWeight := unit.Pound(274) + adjustedWeight := GetAdjustedWeight(incomingWeight, true) + suite.Equal(unit.Pound(301), *adjustedWeight) + }) + suite.Run("If weight of 1000 is provided UB", func() { + incomingWeight := unit.Pound(1000) + adjustedWeight := GetAdjustedWeight(incomingWeight, true) + suite.Equal(unit.Pound(1100), *adjustedWeight) + }) +} diff --git a/pkg/services/orchestrators/shipment/shipment_updater.go b/pkg/services/orchestrators/shipment/shipment_updater.go index 70b0406a842..d8d82af8e90 100644 --- a/pkg/services/orchestrators/shipment/shipment_updater.go +++ b/pkg/services/orchestrators/shipment/shipment_updater.go @@ -6,6 +6,7 @@ import ( "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/unit" ) // shipmentUpdater is the concrete struct implementing the services.ShipmentUpdater interface @@ -15,16 +16,18 @@ type shipmentUpdater struct { ppmShipmentUpdater services.PPMShipmentUpdater boatShipmentUpdater services.BoatShipmentUpdater mobileHomeShipmentUpdater services.MobileHomeShipmentUpdater + mtoServiceItemCreator services.MTOServiceItemCreator } // NewShipmentUpdater creates a new shipmentUpdater struct with the basic checks and service dependencies. -func NewShipmentUpdater(mtoShipmentUpdater services.MTOShipmentUpdater, ppmShipmentUpdater services.PPMShipmentUpdater, boatShipmentUpdater services.BoatShipmentUpdater, mobileHomeShipmentUpdater services.MobileHomeShipmentUpdater) services.ShipmentUpdater { +func NewShipmentUpdater(mtoShipmentUpdater services.MTOShipmentUpdater, ppmShipmentUpdater services.PPMShipmentUpdater, boatShipmentUpdater services.BoatShipmentUpdater, mobileHomeShipmentUpdater services.MobileHomeShipmentUpdater, mtoServiceItemCreator services.MTOServiceItemCreator) services.ShipmentUpdater { return &shipmentUpdater{ checks: basicShipmentChecks(), mtoShipmentUpdater: mtoShipmentUpdater, ppmShipmentUpdater: ppmShipmentUpdater, boatShipmentUpdater: boatShipmentUpdater, mobileHomeShipmentUpdater: mobileHomeShipmentUpdater, + mtoServiceItemCreator: mtoServiceItemCreator, } } @@ -43,6 +46,20 @@ func (s *shipmentUpdater) UpdateShipment(appCtx appcontext.AppContext, shipment return err } + if mtoShipment != nil && (mtoShipment.ShipmentType != models.MTOShipmentTypePPM) && (shipment.PrimeEstimatedWeight != nil || mtoShipment.PrimeEstimatedWeight != nil) && mtoShipment.Status == models.MTOShipmentStatusApproved { + mtoShipment, err = AddPricingEstimatesToMTOServiceItems(appCtx, *s, mtoShipment, shipment) + if err != nil { + return err + } + } + + if mtoShipment.MTOServiceItems != nil { + _, mtoErr := appCtx.DB().ValidateAndUpdate(&mtoShipment.MTOServiceItems) + if mtoErr != nil { + return mtoErr + } + } + isBoatShipment := shipment.ShipmentType == models.MTOShipmentTypeBoatHaulAway || shipment.ShipmentType == models.MTOShipmentTypeBoatTowAway if shipment.ShipmentType == models.MTOShipmentTypePPM { @@ -122,3 +139,30 @@ func (s *shipmentUpdater) UpdateShipment(appCtx appcontext.AppContext, shipment return mtoShipment, nil } + +func AddPricingEstimatesToMTOServiceItems(appCtx appcontext.AppContext, shipmentUpdater shipmentUpdater, mtoShipment *models.MTOShipment, shipmentDelta *models.MTOShipment) (*models.MTOShipment, error) { + mtoShipmentCopy := mtoShipment + + for index, serviceItem := range mtoShipmentCopy.MTOServiceItems { + var estimatedWeightToUse unit.Pound + if shipmentDelta.PrimeEstimatedWeight != nil { + estimatedWeightToUse = *shipmentDelta.PrimeEstimatedWeight + } else { + estimatedWeightToUse = *mtoShipmentCopy.PrimeEstimatedWeight + } + + serviceItemEstimatedPrice, err := shipmentUpdater.mtoServiceItemCreator.FindEstimatedPrice(appCtx, &serviceItem, *mtoShipment) + + // store actual captured weight + mtoShipmentCopy.MTOServiceItems[index].EstimatedWeight = &estimatedWeightToUse + mtoShipmentCopy.PrimeEstimatedWeight = &estimatedWeightToUse + + if serviceItemEstimatedPrice != 0 && err == nil { + mtoShipmentCopy.MTOServiceItems[index].PricingEstimate = &serviceItemEstimatedPrice + } + if err != nil { + return mtoShipmentCopy, err + } + } + return mtoShipmentCopy, nil +} diff --git a/pkg/services/orchestrators/shipment/shipment_updater_test.go b/pkg/services/orchestrators/shipment/shipment_updater_test.go index 3e46c05d001..3b9fec24cac 100644 --- a/pkg/services/orchestrators/shipment/shipment_updater_test.go +++ b/pkg/services/orchestrators/shipment/shipment_updater_test.go @@ -2,6 +2,7 @@ package shipment import ( "fmt" + "time" "github.com/gofrs/uuid" "github.com/stretchr/testify/mock" @@ -11,8 +12,14 @@ import ( "github.com/transcom/mymove/pkg/etag" "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" + routemocks "github.com/transcom/mymove/pkg/route/mocks" "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/services/ghcrateengine" "github.com/transcom/mymove/pkg/services/mocks" + moveservices "github.com/transcom/mymove/pkg/services/move" + mtoserviceitem "github.com/transcom/mymove/pkg/services/mto_service_item" + "github.com/transcom/mymove/pkg/services/query" + "github.com/transcom/mymove/pkg/testdatagen" "github.com/transcom/mymove/pkg/unit" ) @@ -28,6 +35,7 @@ func (suite *ShipmentSuite) TestUpdateShipment() { type subtestDataObjects struct { mockMTOShipmentUpdater *mocks.MTOShipmentUpdater + mockMtoServiceItemCreator *mocks.MTOServiceItemCreator mockPPMShipmentUpdater *mocks.PPMShipmentUpdater mockBoatShipmentUpdater *mocks.BoatShipmentUpdater mockMobileHomeShipmentUpdater *mocks.MobileHomeShipmentUpdater @@ -36,10 +44,18 @@ func (suite *ShipmentSuite) TestUpdateShipment() { fakeError error } + planner := &routemocks.Planner{} + moveRouter := moveservices.NewMoveRouter() + builder := query.NewQueryBuilder() + mtoServiceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + makeSubtestData := func(returnErrorForMTOShipment bool, returnErrorForPPMShipment bool, returnErrorForBoatShipment bool, returnErrorForMobileHomeShipment bool) (subtestData subtestDataObjects) { mockMTOShipmentUpdater := mocks.MTOShipmentUpdater{} subtestData.mockMTOShipmentUpdater = &mockMTOShipmentUpdater + mockMtoServiceItemCreator := mocks.MTOServiceItemCreator{} + subtestData.mockMtoServiceItemCreator = &mockMtoServiceItemCreator + mockPPMShipmentUpdater := mocks.PPMShipmentUpdater{} subtestData.mockPPMShipmentUpdater = &mockPPMShipmentUpdater @@ -49,9 +65,8 @@ func (suite *ShipmentSuite) TestUpdateShipment() { mockMobileHomeShipmentUpdater := mocks.MobileHomeShipmentUpdater{} subtestData.mockMobileHomeShipmentUpdater = &mockMobileHomeShipmentUpdater - subtestData.shipmentUpdaterOrchestrator = NewShipmentUpdater(subtestData.mockMTOShipmentUpdater, subtestData.mockPPMShipmentUpdater, subtestData.mockBoatShipmentUpdater, subtestData.mockMobileHomeShipmentUpdater) - - subtestData.shipmentUpdaterOrchestrator = NewShipmentUpdater(subtestData.mockMTOShipmentUpdater, subtestData.mockPPMShipmentUpdater, subtestData.mockBoatShipmentUpdater, subtestData.mockMobileHomeShipmentUpdater) + subtestData.shipmentUpdaterOrchestrator = NewShipmentUpdater(subtestData.mockMTOShipmentUpdater, subtestData.mockPPMShipmentUpdater, subtestData.mockBoatShipmentUpdater, subtestData.mockMobileHomeShipmentUpdater, mtoServiceItemCreator) + subtestData.shipmentUpdaterOrchestrator = NewShipmentUpdater(subtestData.mockMTOShipmentUpdater, subtestData.mockPPMShipmentUpdater, subtestData.mockBoatShipmentUpdater, subtestData.mockMobileHomeShipmentUpdater, mtoServiceItemCreator) if returnErrorForMTOShipment { subtestData.fakeError = apperror.NewInvalidInputError(uuid.Nil, nil, nil, "Pickup date missing") @@ -177,6 +192,26 @@ func (suite *ShipmentSuite) TestUpdateShipment() { return subtestData } + makeServiceItemSubtestData := func() (subtestData subtestDataObjects) { + mockMTOShipmentUpdater := mocks.MTOShipmentUpdater{} + subtestData.mockMTOShipmentUpdater = &mockMTOShipmentUpdater + + mockMtoServiceItemCreator := mocks.MTOServiceItemCreator{} + subtestData.mockMtoServiceItemCreator = &mockMtoServiceItemCreator + + mockPPMShipmentUpdater := mocks.PPMShipmentUpdater{} + subtestData.mockPPMShipmentUpdater = &mockPPMShipmentUpdater + + mockBoatShipmentUpdater := mocks.BoatShipmentUpdater{} + subtestData.mockBoatShipmentUpdater = &mockBoatShipmentUpdater + + mockMobileHomeShipmentUpdater := mocks.MobileHomeShipmentUpdater{} + subtestData.mockMobileHomeShipmentUpdater = &mockMobileHomeShipmentUpdater + + subtestData.shipmentUpdaterOrchestrator = NewShipmentUpdater(subtestData.mockMTOShipmentUpdater, subtestData.mockPPMShipmentUpdater, subtestData.mockBoatShipmentUpdater, subtestData.mockMobileHomeShipmentUpdater, subtestData.mockMtoServiceItemCreator) + + return subtestData + } suite.Run("Returns an InvalidInputError if there is an error with the shipment info that was input", func() { appCtx := suite.AppContextForTest() @@ -465,4 +500,133 @@ func (suite *ShipmentSuite) TestUpdateShipment() { mock.AnythingOfType("uuid.UUID"), ) }) + + suite.Run("Updating weight will update the estimated price of service items", func() { + appCtx := suite.AppContextForTest() + + subtestData := makeServiceItemSubtestData() + + estimatedWeight := unit.Pound(2000) + pickupAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress2}) + deliveryAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress3}) + + shipment := factory.BuildMTOShipment(appCtx.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + ID: uuid.Must(uuid.FromString("a5e95c1d-97c3-4f79-8097-c12dd2557ac7")), + Status: models.MTOShipmentStatusApproved, + ShipmentType: models.MTOShipmentTypeHHG, + PrimeEstimatedWeight: &estimatedWeight, + }, + }, + { + Model: pickupAddress, + LinkOnly: true, + Type: &factory.Addresses.PickupAddress, + }, + { + Model: deliveryAddress, + LinkOnly: true, + Type: &factory.Addresses.DeliveryAddress, + }, + }, nil) + + reServiceCodeFSC := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeFSC) + + startDate := time.Now().AddDate(-1, 0, 0) + endDate := startDate.AddDate(1, 1, 1) + reason := "lorem ipsum" + + testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + testdatagen.FetchOrMakeReContractYear(suite.DB(), + testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + Name: "Test Contract Year", + EscalationCompounded: 1.125, + StartDate: startDate, + EndDate: endDate, + }, + }) + + testdatagen.FetchOrMakeGHCDieselFuelPrice(suite.DB(), testdatagen.Assertions{ + GHCDieselFuelPrice: models.GHCDieselFuelPrice{ + FuelPriceInMillicents: unit.Millicents(281400), + PublicationDate: time.Date(2020, time.March, 9, 0, 0, 0, 0, time.UTC), + EffectiveDate: time.Date(2020, time.March, 10, 0, 0, 0, 0, time.UTC), + EndDate: time.Date(2025, time.March, 17, 0, 0, 0, 0, time.UTC), + }, + }) + + actualPickupAddress := factory.BuildAddress(suite.DB(), nil, []factory.Trait{factory.GetTraitAddress2}) + requestedPickupDate := time.Date(2020, time.October, 24, 0, 0, 0, 0, time.UTC) + + serviceItemFSC := models.MTOServiceItem{ + MoveTaskOrder: shipment.MoveTaskOrder, + MoveTaskOrderID: shipment.MoveTaskOrderID, + MTOShipment: shipment, + MTOShipmentID: &shipment.ID, + ReService: reServiceCodeFSC, + Reason: &reason, + SITOriginHHGActualAddress: &actualPickupAddress, + Status: models.MTOServiceItemStatusSubmitted, + } + + shipment.MTOServiceItems = append(shipment.MTOServiceItems, serviceItemFSC) + suite.MustSave(&shipment) + + eTag := etag.GenerateEtag(shipment.UpdatedAt) + + subtestData.mockMtoServiceItemCreator.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + false, + ).Return(800, nil) + + returnCents := unit.Cents(123) + + subtestData.mockMtoServiceItemCreator.On("FindEstimatedPrice", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + mock.Anything, + ).Return(returnCents, nil) + + subtestData.mockMTOShipmentUpdater. + On( + updateMTOShipmentMethodName, + mock.AnythingOfType("*appcontext.appContext"), + mock.AnythingOfType("*models.MTOShipment"), + mock.AnythingOfType("string"), + mock.AnythingOfType("string")). + Return( + &models.MTOShipment{ + ID: uuid.Must(uuid.FromString("a5e95c1d-97c3-4f79-8097-c12dd2557ac7")), + Status: models.MTOShipmentStatusApproved, + ShipmentType: models.MTOShipmentTypeHHG, + PrimeEstimatedWeight: &estimatedWeight, + RequestedPickupDate: &requestedPickupDate, + MTOServiceItems: models.MTOServiceItems{serviceItemFSC}, + PickupAddress: &pickupAddress, + DestinationAddress: &deliveryAddress, + }, nil) + + // Need to start a transaction so we can assert the call with the correct appCtx + err := appCtx.NewTransaction(func(txAppCtx appcontext.AppContext) error { + mtoShipment, err := subtestData.shipmentUpdaterOrchestrator.UpdateShipment(txAppCtx, &shipment, eTag, "test") + + suite.NoError(err) + suite.NotNil(mtoShipment) + + expectedPrice := unit.Cents(123) + expectedWeight := unit.Pound(2000) + suite.Equal(expectedWeight, *mtoShipment.MTOServiceItems[0].EstimatedWeight) + suite.Equal(expectedPrice, *mtoShipment.MTOServiceItems[0].PricingEstimate) + + return nil + }) + + suite.NoError(err) // just making golangci-lint happy + }) }