From cbc054b427b3485acd11d1f5441201aa48d05c88 Mon Sep 17 00:00:00 2001 From: Michael Inthavongsay Date: Mon, 16 Dec 2024 21:52:16 +0000 Subject: [PATCH 01/52] add validation to restrict create service item for PPM --- pkg/handlers/primeapi/mto_service_item.go | 20 ++++ .../primeapi/mto_service_item_test.go | 97 +++++++++++++++++-- pkg/handlers/primeapiv2/mto_service_item.go | 20 ++++ .../primeapiv2/mto_service_item_test.go | 97 +++++++++++++++++-- pkg/handlers/primeapiv3/mto_service_item.go | 22 ++++- .../primeapiv3/mto_service_item_test.go | 97 +++++++++++++++++-- pkg/models/mto_shipments.go | 19 ++++ pkg/models/mto_shipments_test.go | 15 +++ 8 files changed, 365 insertions(+), 22 deletions(-) diff --git a/pkg/handlers/primeapi/mto_service_item.go b/pkg/handlers/primeapi/mto_service_item.go index f704b84758c..4c895751deb 100644 --- a/pkg/handlers/primeapi/mto_service_item.go +++ b/pkg/handlers/primeapi/mto_service_item.go @@ -44,6 +44,26 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe return h.AuditableAppContextFromRequestWithErrors(params.HTTPRequest, func(appCtx appcontext.AppContext) (middleware.Responder, error) { + // ** Create service item can not be done for PPM shipment **/ + shipment, err := models.FetchShipmentByID(appCtx.DB(), uuid.FromStringOrNil(params.Body.MtoShipmentID().String())) + if err != nil { + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler Error Fetch Shipment", zap.Error(err)) + switch err { + case models.ErrFetchNotFound: + return mtoserviceitemops.NewCreateMTOServiceItemNotFound().WithPayload(payloads.ClientError(handlers.NotFoundMessage, "Fetch Shipment", h.GetTraceIDFromRequest(params.HTTPRequest))), err + default: + return mtoserviceitemops.NewCreateMTOServiceItemInternalServerError().WithPayload(payloads.InternalServerError(nil, h.GetTraceIDFromRequest(params.HTTPRequest))), err + } + } + + if shipment.ShipmentType == models.MTOShipmentTypePPM { + verrs := validate.NewErrors() + verrs.Add("ShipmentType", string(shipment.ShipmentType)) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler error", zap.Error(verrs)) + return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(payloads.ValidationError( + "Create Service Item is not allowed", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs + } + /** Feature Flag - Alaska **/ isAlaskaEnabled := false featureFlagName := "enable_alaska" diff --git a/pkg/handlers/primeapi/mto_service_item_test.go b/pkg/handlers/primeapi/mto_service_item_test.go index c3e8b9daef6..5af4ea4b8cf 100644 --- a/pkg/handlers/primeapi/mto_service_item_test.go +++ b/pkg/handlers/primeapi/mto_service_item_test.go @@ -42,16 +42,33 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mtoServiceItem models.MTOServiceItem } - makeSubtestData := func() (subtestData *localSubtestData) { + makeSubtestDataWithPPMShipmentType := func(isPPM bool) (subtestData *localSubtestData) { subtestData = &localSubtestData{} + mtoShipmentID, _ := uuid.NewV4() mto := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) - subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ - { - Model: mto, - LinkOnly: true, - }, - }, nil) + if isPPM { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + ID: mtoShipmentID, + ShipmentType: models.MTOShipmentTypePPM, + }, + }, + }, nil) + } else { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + }, nil) + } + factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOFSIT) req := httptest.NewRequest("POST", "/mto-service-items", nil) sitEntryDate := time.Now() @@ -85,6 +102,10 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { return subtestData } + makeSubtestData := func() (subtestData *localSubtestData) { + return makeSubtestDataWithPPMShipmentType(false) + } + suite.Run("Successful POST - Integration Test", func() { subtestData := makeSubtestData() moveRouter := moverouter.NewMoveRouter() @@ -426,6 +447,68 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // Validate outgoing payload suite.NoError(responsePayload.Validate(strfmt.Default)) }) + + suite.Run("POST failure - Shipment fetch not found", func() { + subtestData := makeSubtestDataWithPPMShipmentType(true) + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + // we are going to mock fake UUID to force NOT FOUND ERROR + subtestData.params.Body.SetMtoShipmentID(subtestData.params.Body.ID()) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemNotFound{}, response) + typedResponse := response.(*mtoserviceitemops.CreateMTOServiceItemNotFound) + + // Validate outgoing payload + suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) + + suite.Contains(*typedResponse.Payload.Detail, "Fetch Shipment") + }) + + suite.Run("POST failure - 422 - PPM not allowed to create service item", func() { + subtestData := makeSubtestDataWithPPMShipmentType(true) + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemUnprocessableEntity{}, response) + typedResponse := response.(*mtoserviceitemops.CreateMTOServiceItemUnprocessableEntity) + + // Validate outgoing payload + suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) + + suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed") + suite.Contains(typedResponse.Payload.InvalidFields["ShipmentType"][0], "PPM") + }) } func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { diff --git a/pkg/handlers/primeapiv2/mto_service_item.go b/pkg/handlers/primeapiv2/mto_service_item.go index e26332964c8..295590e0c7e 100644 --- a/pkg/handlers/primeapiv2/mto_service_item.go +++ b/pkg/handlers/primeapiv2/mto_service_item.go @@ -42,6 +42,26 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe return h.AuditableAppContextFromRequestWithErrors(params.HTTPRequest, func(appCtx appcontext.AppContext) (middleware.Responder, error) { + // ** Create service item can not be done for PPM shipment **/ + shipment, err := models.FetchShipmentByID(appCtx.DB(), uuid.FromStringOrNil(params.Body.MtoShipmentID().String())) + if err != nil { + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v2 Error Fetch Shipment", zap.Error(err)) + switch err { + case models.ErrFetchNotFound: + return mtoserviceitemops.NewCreateMTOServiceItemNotFound().WithPayload(primeapipayloads.ClientError(handlers.NotFoundMessage, "Fetch Shipment", h.GetTraceIDFromRequest(params.HTTPRequest))), err + default: + return mtoserviceitemops.NewCreateMTOServiceItemInternalServerError().WithPayload(primeapipayloads.InternalServerError(nil, h.GetTraceIDFromRequest(params.HTTPRequest))), err + } + } + + if shipment.ShipmentType == models.MTOShipmentTypePPM { + verrs := validate.NewErrors() + verrs.Add("ShipmentType", string(shipment.ShipmentType)) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v2 error", zap.Error(verrs)) + return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(primeapipayloads.ValidationError( + "Create Service Item is not allowed", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs + } + /** Feature Flag - Alaska **/ isAlaskaEnabled := false featureFlagName := "enable_alaska" diff --git a/pkg/handlers/primeapiv2/mto_service_item_test.go b/pkg/handlers/primeapiv2/mto_service_item_test.go index ffe960ba4f4..e8822ea2822 100644 --- a/pkg/handlers/primeapiv2/mto_service_item_test.go +++ b/pkg/handlers/primeapiv2/mto_service_item_test.go @@ -37,16 +37,33 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mtoServiceItem models.MTOServiceItem } - makeSubtestData := func() (subtestData *localSubtestData) { + makeSubtestDataWithPPMShipmentType := func(isPPM bool) (subtestData *localSubtestData) { subtestData = &localSubtestData{} + mtoShipmentID, _ := uuid.NewV4() + mto := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) - subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ - { - Model: mto, - LinkOnly: true, - }, - }, nil) + if isPPM { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + ID: mtoShipmentID, + ShipmentType: models.MTOShipmentTypePPM, + }, + }, + }, nil) + } else { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + }, nil) + } factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOFSIT) req := httptest.NewRequest("POST", "/mto-service-items", nil) sitEntryDate := time.Now() @@ -80,6 +97,10 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { return subtestData } + makeSubtestData := func() (subtestData *localSubtestData) { + return makeSubtestDataWithPPMShipmentType(false) + } + suite.Run("Successful POST - Integration Test", func() { subtestData := makeSubtestData() moveRouter := moverouter.NewMoveRouter() @@ -421,6 +442,68 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // Validate outgoing payload suite.NoError(responsePayload.Validate(strfmt.Default)) }) + + suite.Run("POST failure - Shipment fetch not found", func() { + subtestData := makeSubtestDataWithPPMShipmentType(true) + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + // we are going to mock fake UUID to force NOT FOUND ERROR + subtestData.params.Body.SetMtoShipmentID(subtestData.params.Body.ID()) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemNotFound{}, response) + typedResponse := response.(*mtoserviceitemops.CreateMTOServiceItemNotFound) + + // Validate outgoing payload + suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) + + suite.Contains(*typedResponse.Payload.Detail, "Fetch Shipment") + }) + + suite.Run("POST failure - 422 - PPM not allowed to create service item", func() { + subtestData := makeSubtestDataWithPPMShipmentType(true) + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemUnprocessableEntity{}, response) + typedResponse := response.(*mtoserviceitemops.CreateMTOServiceItemUnprocessableEntity) + + // Validate outgoing payload + suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) + + suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed") + suite.Contains(typedResponse.Payload.InvalidFields["ShipmentType"][0], "PPM") + }) } func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { diff --git a/pkg/handlers/primeapiv3/mto_service_item.go b/pkg/handlers/primeapiv3/mto_service_item.go index 4b83e3d1fd2..3eb6a9decbe 100644 --- a/pkg/handlers/primeapiv3/mto_service_item.go +++ b/pkg/handlers/primeapiv3/mto_service_item.go @@ -42,6 +42,26 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe return h.AuditableAppContextFromRequestWithErrors(params.HTTPRequest, func(appCtx appcontext.AppContext) (middleware.Responder, error) { + // ** Create service item can not be done for PPM shipment **/ + shipment, err := models.FetchShipmentByID(appCtx.DB(), uuid.FromStringOrNil(params.Body.MtoShipmentID().String())) + if err != nil { + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v3 Error Fetch Shipment", zap.Error(err)) + switch err { + case models.ErrFetchNotFound: + return mtoserviceitemops.NewCreateMTOServiceItemNotFound().WithPayload(primeapipayloads.ClientError(handlers.NotFoundMessage, "Fetch Shipment", h.GetTraceIDFromRequest(params.HTTPRequest))), err + default: + return mtoserviceitemops.NewCreateMTOServiceItemInternalServerError().WithPayload(primeapipayloads.InternalServerError(nil, h.GetTraceIDFromRequest(params.HTTPRequest))), err + } + } + + if shipment.ShipmentType == models.MTOShipmentTypePPM { + verrs := validate.NewErrors() + verrs.Add("ShipmentType", string(shipment.ShipmentType)) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v3 error", zap.Error(verrs)) + return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(primeapipayloads.ValidationError( + "Create Service Item is not allowed", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs + } + /** Feature Flag - Alaska **/ isAlaskaEnabled := false featureFlagName := "enable_alaska" @@ -65,7 +85,7 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe verrs := validate.NewErrors() verrs.Add("modelType", fmt.Sprintf("allowed modelType() %v", mapKeys)) - appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler error", zap.Error(verrs)) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v3 error", zap.Error(verrs)) return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(primeapipayloads.ValidationError( detailErr, h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs } diff --git a/pkg/handlers/primeapiv3/mto_service_item_test.go b/pkg/handlers/primeapiv3/mto_service_item_test.go index 1bc9362127c..5cf7ecbdd81 100644 --- a/pkg/handlers/primeapiv3/mto_service_item_test.go +++ b/pkg/handlers/primeapiv3/mto_service_item_test.go @@ -37,16 +37,33 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mtoServiceItem models.MTOServiceItem } - makeSubtestData := func() (subtestData *localSubtestData) { + makeSubtestDataWithPPMShipmentType := func(isPPM bool) (subtestData *localSubtestData) { subtestData = &localSubtestData{} + mtoShipmentID, _ := uuid.NewV4() + mto := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) - subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ - { - Model: mto, - LinkOnly: true, - }, - }, nil) + if isPPM { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + ID: mtoShipmentID, + ShipmentType: models.MTOShipmentTypePPM, + }, + }, + }, nil) + } else { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + }, nil) + } factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOFSIT) req := httptest.NewRequest("POST", "/mto-service-items", nil) sitEntryDate := time.Now() @@ -81,6 +98,10 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { return subtestData } + makeSubtestData := func() (subtestData *localSubtestData) { + return makeSubtestDataWithPPMShipmentType(false) + } + suite.Run("Successful POST - Integration Test", func() { planner := &routemocks.Planner{} planner.On("ZipTransitDistance", @@ -422,6 +443,68 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // Validate outgoing payload suite.NoError(responsePayload.Validate(strfmt.Default)) }) + + suite.Run("POST failure - Shipment fetch not found", func() { + subtestData := makeSubtestDataWithPPMShipmentType(true) + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + // we are going to mock fake UUID to force NOT FOUND ERROR + subtestData.params.Body.SetMtoShipmentID(subtestData.params.Body.ID()) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemNotFound{}, response) + typedResponse := response.(*mtoserviceitemops.CreateMTOServiceItemNotFound) + + // Validate outgoing payload + suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) + + suite.Contains(*typedResponse.Payload.Detail, "Fetch Shipment") + }) + + suite.Run("POST failure - 422 - PPM not allowed to create service item", func() { + subtestData := makeSubtestDataWithPPMShipmentType(true) + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemUnprocessableEntity{}, response) + typedResponse := response.(*mtoserviceitemops.CreateMTOServiceItemUnprocessableEntity) + + // Validate outgoing payload + suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) + + suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed") + suite.Contains(typedResponse.Payload.InvalidFields["ShipmentType"][0], "PPM") + }) } func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index 108c49b49b5..005874e9824 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -8,6 +8,7 @@ import ( "github.com/gobuffalo/validate/v3" "github.com/gobuffalo/validate/v3/validators" "github.com/gofrs/uuid" + "github.com/pkg/errors" "github.com/transcom/mymove/pkg/unit" ) @@ -280,6 +281,10 @@ func (m MTOShipment) ContainsAPPMShipment() bool { return m.PPMShipment != nil } +func (m MTOShipment) IsPPMShipment() bool { + return m.ShipmentType == MTOShipmentTypePPM +} + // determining the market code for a shipment based off of address isOconus value // this function takes in a shipment and returns the same shipment with the updated MarketCode value func DetermineShipmentMarketCode(shipment *MTOShipment) *MTOShipment { @@ -369,3 +374,17 @@ func CreateApprovedServiceItemsForShipment(db *pop.Connection, shipment *MTOShip return nil } + +// Returns a Shipment for a given id +func FetchShipmentByID(db *pop.Connection, shipmentID uuid.UUID) (*MTOShipment, error) { + var mtoShipment MTOShipment + err := db.Q().Find(&mtoShipment, shipmentID) + + if err != nil { + if errors.Cause(err).Error() == RecordNotFoundErrorString { + return nil, ErrFetchNotFound + } + return nil, err + } + return &mtoShipment, nil +} diff --git a/pkg/models/mto_shipments_test.go b/pkg/models/mto_shipments_test.go index 5f2a5f78864..0af9121e013 100644 --- a/pkg/models/mto_shipments_test.go +++ b/pkg/models/mto_shipments_test.go @@ -324,3 +324,18 @@ func (suite *ModelSuite) TestCreateApprovedServiceItemsForShipment() { suite.Error(err) }) } + +func (suite *ModelSuite) TestFindShipmentByID() { + suite.Run("success - test find", func() { + shipment := factory.BuildMTOShipmentMinimal(suite.DB(), nil, nil) + _, err := models.FetchShipmentByID(suite.DB(), shipment.ID) + suite.NoError(err) + }) + + suite.Run("not found test find", func() { + notValidID := uuid.Must(uuid.NewV4()) + _, err := models.FetchShipmentByID(suite.DB(), notValidID) + suite.Error(err) + suite.Equal(models.ErrFetchNotFound, err) + }) +} From 310ea05e068fdbb13e49e3d1d7cab9e9d11dcedf Mon Sep 17 00:00:00 2001 From: Michael Inthavongsay Date: Wed, 18 Dec 2024 18:19:40 +0000 Subject: [PATCH 02/52] update response error message to make it user friendly --- pkg/handlers/primeapi/mto_service_item.go | 6 +++--- pkg/handlers/primeapi/mto_service_item_test.go | 4 ++-- pkg/handlers/primeapiv2/mto_service_item.go | 6 +++--- pkg/handlers/primeapiv2/mto_service_item_test.go | 4 ++-- pkg/handlers/primeapiv3/mto_service_item.go | 6 +++--- pkg/handlers/primeapiv3/mto_service_item_test.go | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/handlers/primeapi/mto_service_item.go b/pkg/handlers/primeapi/mto_service_item.go index 4c895751deb..4e60ef720bb 100644 --- a/pkg/handlers/primeapi/mto_service_item.go +++ b/pkg/handlers/primeapi/mto_service_item.go @@ -58,10 +58,10 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe if shipment.ShipmentType == models.MTOShipmentTypePPM { verrs := validate.NewErrors() - verrs.Add("ShipmentType", string(shipment.ShipmentType)) - appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler error", zap.Error(verrs)) + verrs.Add("mtoShipmentID", params.Body.MtoShipmentID().String()) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler - Create Service Item is not allowed for PPM shipments", zap.Error(verrs)) return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(payloads.ValidationError( - "Create Service Item is not allowed", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs + "Create Service Item is not allowed for PPM shipments", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs } /** Feature Flag - Alaska **/ diff --git a/pkg/handlers/primeapi/mto_service_item_test.go b/pkg/handlers/primeapi/mto_service_item_test.go index 5af4ea4b8cf..699255d1c85 100644 --- a/pkg/handlers/primeapi/mto_service_item_test.go +++ b/pkg/handlers/primeapi/mto_service_item_test.go @@ -506,8 +506,8 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // Validate outgoing payload suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) - suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed") - suite.Contains(typedResponse.Payload.InvalidFields["ShipmentType"][0], "PPM") + suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed for PPM shipments") + suite.Contains(typedResponse.Payload.InvalidFields["mtoShipmentID"][0], subtestData.params.Body.MtoShipmentID().String()) }) } diff --git a/pkg/handlers/primeapiv2/mto_service_item.go b/pkg/handlers/primeapiv2/mto_service_item.go index 295590e0c7e..54ea0540344 100644 --- a/pkg/handlers/primeapiv2/mto_service_item.go +++ b/pkg/handlers/primeapiv2/mto_service_item.go @@ -56,10 +56,10 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe if shipment.ShipmentType == models.MTOShipmentTypePPM { verrs := validate.NewErrors() - verrs.Add("ShipmentType", string(shipment.ShipmentType)) - appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v2 error", zap.Error(verrs)) + verrs.Add("mtoShipmentID", params.Body.MtoShipmentID().String()) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v2 - Create Service Item is not allowed for PPM shipments", zap.Error(verrs)) return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(primeapipayloads.ValidationError( - "Create Service Item is not allowed", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs + "Create Service Item is not allowed for PPM shipments", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs } /** Feature Flag - Alaska **/ diff --git a/pkg/handlers/primeapiv2/mto_service_item_test.go b/pkg/handlers/primeapiv2/mto_service_item_test.go index e8822ea2822..c34d9e69cb1 100644 --- a/pkg/handlers/primeapiv2/mto_service_item_test.go +++ b/pkg/handlers/primeapiv2/mto_service_item_test.go @@ -501,8 +501,8 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // Validate outgoing payload suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) - suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed") - suite.Contains(typedResponse.Payload.InvalidFields["ShipmentType"][0], "PPM") + suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed for PPM shipments") + suite.Contains(typedResponse.Payload.InvalidFields["mtoShipmentID"][0], subtestData.params.Body.MtoShipmentID().String()) }) } diff --git a/pkg/handlers/primeapiv3/mto_service_item.go b/pkg/handlers/primeapiv3/mto_service_item.go index 3eb6a9decbe..ef7528e4ddf 100644 --- a/pkg/handlers/primeapiv3/mto_service_item.go +++ b/pkg/handlers/primeapiv3/mto_service_item.go @@ -56,10 +56,10 @@ func (h CreateMTOServiceItemHandler) Handle(params mtoserviceitemops.CreateMTOSe if shipment.ShipmentType == models.MTOShipmentTypePPM { verrs := validate.NewErrors() - verrs.Add("ShipmentType", string(shipment.ShipmentType)) - appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v3 error", zap.Error(verrs)) + verrs.Add("mtoShipmentID", params.Body.MtoShipmentID().String()) + appCtx.Logger().Error("primeapi.CreateMTOServiceItemHandler.v3 - Create Service Item is not allowed for PPM shipments", zap.Error(verrs)) return mtoserviceitemops.NewCreateMTOServiceItemUnprocessableEntity().WithPayload(primeapipayloads.ValidationError( - "Create Service Item is not allowed", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs + "Create Service Item is not allowed for PPM shipments", h.GetTraceIDFromRequest(params.HTTPRequest), verrs)), verrs } /** Feature Flag - Alaska **/ diff --git a/pkg/handlers/primeapiv3/mto_service_item_test.go b/pkg/handlers/primeapiv3/mto_service_item_test.go index 5cf7ecbdd81..39afcbafc34 100644 --- a/pkg/handlers/primeapiv3/mto_service_item_test.go +++ b/pkg/handlers/primeapiv3/mto_service_item_test.go @@ -502,8 +502,8 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // Validate outgoing payload suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) - suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed") - suite.Contains(typedResponse.Payload.InvalidFields["ShipmentType"][0], "PPM") + suite.Contains(*typedResponse.Payload.Detail, "Create Service Item is not allowed for PPM shipments") + suite.Contains(typedResponse.Payload.InvalidFields["mtoShipmentID"][0], subtestData.params.Body.MtoShipmentID().String()) }) } From c5456eb4c0cfef4ca6e15fd8f4d9ddcd20519942 Mon Sep 17 00:00:00 2001 From: Beth Grohmann Date: Fri, 27 Dec 2024 14:29:41 -0600 Subject: [PATCH 03/52] Add Camp Pendelton transportation office --- migrations/app/migrations_manifest.txt | 1 + ...sert_transportation_offices_camp_pendelton.up.sql | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index ce1d2a281d2..6dc31cb265a 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1050,3 +1050,4 @@ 20241203024453_add_ppm_max_incentive_column.up.sql 20241204155919_update_ordering_proc.up.sql 20241204210208_retroactive_update_of_ppm_max_and_estimated_incentives_prd.up.sql +20241227202424_insert_transportation_offices_camp_pendelton.up.sql diff --git a/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql b/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql new file mode 100644 index 00000000000..a479d4d4d48 --- /dev/null +++ b/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql @@ -0,0 +1,12 @@ +--add address for Camp Pendelton transportation office +INSERT INTO public.addresses +(id, street_address_1, street_address_2, city, state, postal_code, created_at, updated_at, street_address_3, county, is_oconus, country_id, us_post_region_cities_id) +VALUES('da815bc4-2b66-41ba-83de-7abd161ac74b', 'Vandergrift Blvd', 'Bldg 2263', 'Camp Pendelton', 'CA', '92054', now(), now(), null, 'SAN DIEGO', false, '791899e6-cd77-46f2-981b-176ecb8d7098','d0c818dc-1e6c-416a-bfa9-2762efebaed1' ); + +--add Camp Pendelton transportation office +INSERT INTO public.transportation_offices +(id, shipping_office_id, "name", address_id, latitude, longitude, hours, services, note, created_at, updated_at, gbloc, provides_ppm_closeout) +VALUES('9cd498c6-8ccb-48c4-9d1f-64338de132c2', '27002d34-e9ea-4ef5-a086-f23d07c4088c', 'PPPO DMO Camp Pendelton', 'da815bc4-2b66-41ba-83de-7abd161ac74b', 33.295425, -117.3541, null, null, null, now(), now(), 'LKNQ', false); + +--associate duty location to Camp Pendelton transportation office +update duty_locations set transportation_office_id = '9cd498c6-8ccb-48c4-9d1f-64338de132c2' where id = '6e320acb-47b6-45e0-80f4-9d8dc1e20812'; \ No newline at end of file From faa4cde5ebfc11309932486d1facef345d4443d1 Mon Sep 17 00:00:00 2001 From: Beth Grohmann Date: Mon, 30 Dec 2024 12:12:34 -0600 Subject: [PATCH 04/52] Update 20241227202424_insert_transportation_offices_camp_pendelton.up.sql --- ..._transportation_offices_camp_pendelton.up.sql | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql b/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql index a479d4d4d48..3e74d735152 100644 --- a/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql +++ b/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql @@ -1,12 +1,8 @@ ---add address for Camp Pendelton transportation office -INSERT INTO public.addresses -(id, street_address_1, street_address_2, city, state, postal_code, created_at, updated_at, street_address_3, county, is_oconus, country_id, us_post_region_cities_id) -VALUES('da815bc4-2b66-41ba-83de-7abd161ac74b', 'Vandergrift Blvd', 'Bldg 2263', 'Camp Pendelton', 'CA', '92054', now(), now(), null, 'SAN DIEGO', false, '791899e6-cd77-46f2-981b-176ecb8d7098','d0c818dc-1e6c-416a-bfa9-2762efebaed1' ); +--update address for Camp Pendelton transportation office +update addresses set postal_code = '92054', us_post_region_cities_id = 'd0c818dc-1e6c-416a-bfa9-2762efebaed1' where id = 'af2ebb73-54fe-46e0-9525-a4568ceb9e0e'; ---add Camp Pendelton transportation office -INSERT INTO public.transportation_offices -(id, shipping_office_id, "name", address_id, latitude, longitude, hours, services, note, created_at, updated_at, gbloc, provides_ppm_closeout) -VALUES('9cd498c6-8ccb-48c4-9d1f-64338de132c2', '27002d34-e9ea-4ef5-a086-f23d07c4088c', 'PPPO DMO Camp Pendelton', 'da815bc4-2b66-41ba-83de-7abd161ac74b', 33.295425, -117.3541, null, null, null, now(), now(), 'LKNQ', false); +--fix Camp Pendelton transportation office spelling +update transportation_offices set name = 'PPPO DMO Camp Pendelton' where id = 'f50eb7f5-960a-46e8-aa64-6025b44132ab'; ---associate duty location to Camp Pendelton transportation office -update duty_locations set transportation_office_id = '9cd498c6-8ccb-48c4-9d1f-64338de132c2' where id = '6e320acb-47b6-45e0-80f4-9d8dc1e20812'; \ No newline at end of file +--associate duty location to Camp Pendleton transportation office +update duty_locations set transportation_office_id = 'f50eb7f5-960a-46e8-aa64-6025b44132ab' where id = '6e320acb-47b6-45e0-80f4-9d8dc1e20812'; From 1aaa7ff3f7371ac7c4e52d7aa6ca4511a56bfb30 Mon Sep 17 00:00:00 2001 From: deandreJones Date: Thu, 2 Jan 2025 11:07:59 -0600 Subject: [PATCH 05/52] spelling matters --- migrations/app/migrations_manifest.txt | 2 +- playwright/tests/my/mymove/orders.spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 9234f61379d..430f892d9f3 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1051,5 +1051,5 @@ 20241203024453_add_ppm_max_incentive_column.up.sql 20241204155919_update_ordering_proc.up.sql 20241204210208_retroactive_update_of_ppm_max_and_estimated_incentives_prd.up.sql -20241227202424_insert_transportation_offices_camp_pendelton.up.sql 20241227153723_remove_empty_string_emplid_values.up.sql +20241227202424_insert_transportation_offices_camp_pendelton.up.sql diff --git a/playwright/tests/my/mymove/orders.spec.js b/playwright/tests/my/mymove/orders.spec.js index fd3a0cab544..67893b39d53 100644 --- a/playwright/tests/my/mymove/orders.spec.js +++ b/playwright/tests/my/mymove/orders.spec.js @@ -110,7 +110,7 @@ test.describe('(MultiMove) Orders', () => { await page.getByRole('combobox', { name: 'Pay grade' }).selectOption({ label: 'E-7' }); await page .getByRole('combobox', { name: 'Counseling Office' }) - .selectOption({ label: 'PPPO DMO Camp Pendleton - USMC' }); + .selectOption({ label: 'PPPO DMO Camp Pendelton - USMC' }); await customerPage.navigateForward(); await customerPage.waitForPage.ordersUpload(); From b79e9b8b123f6b6b0389d6060583c98b0a391b67 Mon Sep 17 00:00:00 2001 From: deandreJones Date: Thu, 2 Jan 2025 11:54:29 -0600 Subject: [PATCH 06/52] fix playwright --- playwright/tests/my/mymove/orders.spec.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/playwright/tests/my/mymove/orders.spec.js b/playwright/tests/my/mymove/orders.spec.js index 67893b39d53..95f723c4a38 100644 --- a/playwright/tests/my/mymove/orders.spec.js +++ b/playwright/tests/my/mymove/orders.spec.js @@ -107,10 +107,8 @@ test.describe('(MultiMove) Orders', () => { await expect(page.getByLabel('Current duty location')).toBeEmpty(); await customerPage.selectDutyLocation('Marine Corps AS Yuma, AZ 85369', 'origin_duty_location'); + await page.getByRole('combobox', { name: 'Counseling Office' }).selectOption({ label: 'PPPO DMO Camp Pendelton' }); await page.getByRole('combobox', { name: 'Pay grade' }).selectOption({ label: 'E-7' }); - await page - .getByRole('combobox', { name: 'Counseling Office' }) - .selectOption({ label: 'PPPO DMO Camp Pendelton - USMC' }); await customerPage.navigateForward(); await customerPage.waitForPage.ordersUpload(); From 20d3a1aed6dba9c6be71c2a30b5ae2d3669a04d8 Mon Sep 17 00:00:00 2001 From: deandreJones Date: Thu, 2 Jan 2025 12:05:04 -0600 Subject: [PATCH 07/52] i blame beth --- ...27202424_insert_transportation_offices_camp_pendelton.up.sql | 2 +- playwright/tests/my/mymove/orders.spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql b/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql index 3e74d735152..dfe3c278ed9 100644 --- a/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql +++ b/migrations/app/schema/20241227202424_insert_transportation_offices_camp_pendelton.up.sql @@ -2,7 +2,7 @@ update addresses set postal_code = '92054', us_post_region_cities_id = 'd0c818dc-1e6c-416a-bfa9-2762efebaed1' where id = 'af2ebb73-54fe-46e0-9525-a4568ceb9e0e'; --fix Camp Pendelton transportation office spelling -update transportation_offices set name = 'PPPO DMO Camp Pendelton' where id = 'f50eb7f5-960a-46e8-aa64-6025b44132ab'; +update transportation_offices set name = 'PPPO DMO Camp Pendleton' where id = 'f50eb7f5-960a-46e8-aa64-6025b44132ab'; --associate duty location to Camp Pendleton transportation office update duty_locations set transportation_office_id = 'f50eb7f5-960a-46e8-aa64-6025b44132ab' where id = '6e320acb-47b6-45e0-80f4-9d8dc1e20812'; diff --git a/playwright/tests/my/mymove/orders.spec.js b/playwright/tests/my/mymove/orders.spec.js index 95f723c4a38..7c418ee006d 100644 --- a/playwright/tests/my/mymove/orders.spec.js +++ b/playwright/tests/my/mymove/orders.spec.js @@ -107,7 +107,7 @@ test.describe('(MultiMove) Orders', () => { await expect(page.getByLabel('Current duty location')).toBeEmpty(); await customerPage.selectDutyLocation('Marine Corps AS Yuma, AZ 85369', 'origin_duty_location'); - await page.getByRole('combobox', { name: 'Counseling Office' }).selectOption({ label: 'PPPO DMO Camp Pendelton' }); + await page.getByRole('combobox', { name: 'Counseling Office' }).selectOption({ label: 'PPPO DMO Camp Pendleton' }); await page.getByRole('combobox', { name: 'Pay grade' }).selectOption({ label: 'E-7' }); await customerPage.navigateForward(); From 84379c3dad1c5dbd19ae356012d7677dc412d360 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Tue, 17 Dec 2024 14:33:20 +0000 Subject: [PATCH 08/52] initial commit, migration added, need to double check areas where pricing needs to be updated --- migrations/app/migrations_manifest.txt | 3 +- ...190428_update_get_zip_code_function.up.sql | 41 +++++++++++++++++++ pkg/handlers/ghcapi/mto_shipment.go | 12 ++++++ .../mto_shipment/mto_shipment_updater.go | 16 ++++++++ .../mto_shipment/shipment_approver.go | 33 ++++++++++----- .../shipment_address_update_requester.go | 11 +++++ .../ServiceItemDetails/ServiceItemDetails.jsx | 7 +++- 7 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index a31d11f3f55..6720141b026 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1053,9 +1053,10 @@ 20241204155919_update_ordering_proc.up.sql 20241204210208_retroactive_update_of_ppm_max_and_estimated_incentives_prd.up.sql 20241210143143_redefine_mto_shipment_audit_table.up.sql -20241218201833_add_PPPO_BASE_ELIZABETH.up.sql +20241216190428_update_get_zip_code_function.up.sql 20241217163231_update_duty_locations_bad_zips.up.sql 20241217180136_add_AK_zips_to_zip3_distances.up.sql +20241218201833_add_PPPO_BASE_ELIZABETH.up.sql 20241220171035_add_additional_AK_zips_to_zip3_distances.up.sql 20241227153723_remove_empty_string_emplid_values.up.sql 20241230190638_remove_AK_zips_from_zip3.up.sql diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql new file mode 100644 index 00000000000..b5a276de591 --- /dev/null +++ b/migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql @@ -0,0 +1,41 @@ +-- removing the exception that was previously being returned +-- this is to avoid the db update failing for the entire proc it is used in +-- we won't always have the POE/POD locations and want to ignore any errors here +CREATE OR REPLACE FUNCTION get_zip_code(shipment_id uuid, address_type VARCHAR) +RETURNS VARCHAR AS $$ + DECLARE zip_code VARCHAR; + BEGIN + + IF address_type = 'pickup' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_shipments ms + JOIN addresses a ON a.id = ms.pickup_address_id + JOIN v_locations vl ON vl.uprc_id = a.us_post_region_cities_id + WHERE ms.id = shipment_id; + ELSIF address_type = 'destination' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_shipments ms + JOIN addresses a ON a.id = ms.destination_address_id + JOIN v_locations vl ON vl.uprc_id = a.us_post_region_cities_id + WHERE ms.id = shipment_id; + ELSIF address_type = 'poe' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_service_items si + JOIN port_locations pl ON pl.id = si.poe_location_id + JOIN v_locations vl ON vl.uprc_id = pl.us_post_region_cities_id + WHERE si.mto_shipment_id = shipment_id; + ELSIF address_type = 'pod' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_service_items si + JOIN port_locations pl ON pl.id = si.pod_location_id + JOIN v_locations vl ON vl.uprc_id = pl.us_post_region_cities_id + WHERE si.mto_shipment_id = shipment_id; + END IF; + + RETURN zip_code; +END; +$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/pkg/handlers/ghcapi/mto_shipment.go b/pkg/handlers/ghcapi/mto_shipment.go index 9a49401e612..0ab30d6ed1a 100644 --- a/pkg/handlers/ghcapi/mto_shipment.go +++ b/pkg/handlers/ghcapi/mto_shipment.go @@ -1,11 +1,13 @@ package ghcapi import ( + "errors" "fmt" "github.com/go-openapi/runtime/middleware" "github.com/gobuffalo/validate/v3" "github.com/gofrs/uuid" + "github.com/lib/pq" "go.uber.org/zap" "github.com/transcom/mymove/pkg/appcontext" @@ -378,6 +380,16 @@ func (h UpdateShipmentHandler) Handle(params mtoshipmentops.UpdateMTOShipmentPar appCtx.Logger().Error("ghcapi.UpdateShipmentHandler error", zap.Error(e.Unwrap())) } + // Try to unwrap the error to access the underlying pq.Error (aka error from the db) + var pqErr *pq.Error + if errors.As(e.Unwrap(), &pqErr) { + appCtx.Logger().Error("QueryError message", zap.String("databaseError", pqErr.Message)) + databaseErrorMessage := fmt.Sprintf("Database error: %s", pqErr.Message) + return mtoshipmentops.NewUpdateMTOShipmentInternalServerError().WithPayload( + &ghcmessages.Error{Message: &databaseErrorMessage}, + ), err + } + msg := fmt.Sprintf("%v | Instance: %v", handlers.FmtString(err.Error()), h.GetTraceIDFromRequest(params.HTTPRequest)) return mtoshipmentops.NewUpdateMTOShipmentInternalServerError().WithPayload( diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 92ca8ba58c8..251929f0f08 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -850,6 +850,22 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, return err } + // if the shipment has an estimated weight, we need to update the service item pricing + // we only need to do this if the estimated weight, primary addresses, and pickup date are being updated since those all impact pricing + if newShipment.PrimeEstimatedWeight != nil && + newShipment.MarketCode == models.MarketCodeInternational && + (*newShipment.PrimeEstimatedWeight != *dbShipment.PrimeEstimatedWeight || + newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || + newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || + newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { + + // Update the service item pricing if relevant fields have changed + err := models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment) + if err != nil { + return err + } + } + // // Perform shipment recalculate payment request // diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index 52e849e469b..161dde3b721 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -77,13 +77,6 @@ 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 { verrs, err := txnAppCtx.DB().ValidateAndSave(shipment) if verrs != nil && verrs.HasAny() { @@ -95,11 +88,29 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen return err } - // after approving shipment, shipment level service items must be created - err = f.createShipmentServiceItems(txnAppCtx, shipment) - if err != nil { - return err + // create international shipment service items + // we use a database proc to create the basic auto-approved service items + if shipment.ShipmentType == models.MTOShipmentTypeHHG && shipment.MarketCode == models.MarketCodeInternational { + err := models.CreateApprovedServiceItemsForShipment(appCtx.DB(), shipment) + if err != nil { + return err + } + + // Update the service item pricing if we have the estimated weight + if shipment.PrimeEstimatedWeight != nil { + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment) + if err != nil { + return err + } + } + } else { + // after approving shipment, shipment level service items must be created + err = f.createShipmentServiceItems(txnAppCtx, shipment) + if err != nil { + return err + } } + return nil }) diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index 74f9e484e2a..598e64f35cd 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -603,6 +603,17 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc return err } + // if the shipment has an estimated weight, we need to update the service item pricing since we know the distances have changed + // this only applies to international shipments + if shipment.PrimeEstimatedWeight != nil && + shipment.MarketCode == models.MarketCodeInternational { + + err := models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment) + if err != nil { + return err + } + } + _, err = f.moveRouter.ApproveOrRequestApproval(appCtx, shipment.MoveTaskOrder) if err != nil { return err diff --git a/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx b/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx index c6be9ec77af..689a790ca64 100644 --- a/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx +++ b/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx @@ -487,7 +487,12 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s case 'DOP': case 'DDP': case 'DPK': - case 'DUPK': { + case 'DUPK': + case 'ISLH': + case 'IHPK': + case 'IHUPK': + case 'POEFSC': + case 'PODFSC': { detailSection = (
From 63f3a075dad528aa4e08140bd8ab8a140507d284 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Tue, 17 Dec 2024 17:55:38 +0000 Subject: [PATCH 09/52] comments, stuff --- pkg/services/mto_shipment/mto_shipment_updater.go | 1 + .../shipment_address_update/shipment_address_update_requester.go | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 251929f0f08..5c03fb11f71 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -852,6 +852,7 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, // if the shipment has an estimated weight, we need to update the service item pricing // we only need to do this if the estimated weight, primary addresses, and pickup date are being updated since those all impact pricing + // we will compare data here to see if we even need to update the pricing if newShipment.PrimeEstimatedWeight != nil && newShipment.MarketCode == models.MarketCodeInternational && (*newShipment.PrimeEstimatedWeight != *dbShipment.PrimeEstimatedWeight || diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index 598e64f35cd..57d608e255b 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -607,7 +607,6 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc // this only applies to international shipments if shipment.PrimeEstimatedWeight != nil && shipment.MarketCode == models.MarketCodeInternational { - err := models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment) if err != nil { return err From 1d3144f4bc39b240a3a3db95a9019d073da42fb0 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Tue, 17 Dec 2024 21:02:06 +0000 Subject: [PATCH 10/52] updated migration, all tests with added parameter for zip distance calculation --- migrations/app/migrations_manifest.txt | 2 +- ...190428_update_get_zip_code_function.up.sql | 41 ----- ...de_function_and_update_pricing_proc.up.sql | 155 ++++++++++++++++++ pkg/handlers/adminapi/moves_test.go | 1 + pkg/handlers/ghcapi/move_task_order_test.go | 4 + pkg/handlers/ghcapi/mto_service_items_test.go | 4 + pkg/handlers/ghcapi/mto_shipment_test.go | 21 +++ pkg/handlers/ghcapi/orders_test.go | 1 + pkg/handlers/ghcapi/ppm_shipment_test.go | 2 +- pkg/handlers/internalapi/mto_shipment_test.go | 1 + pkg/handlers/primeapi/move_task_order_test.go | 2 + .../primeapi/mto_service_item_test.go | 18 ++ .../primeapi/mto_shipment_address_test.go | 1 + pkg/handlers/primeapi/mto_shipment_test.go | 3 + pkg/handlers/primeapi/payment_request_test.go | 3 + pkg/handlers/primeapi/reweigh_test.go | 1 + .../primeapiv2/mto_service_item_test.go | 16 ++ pkg/handlers/primeapiv2/mto_shipment_test.go | 1 + .../primeapiv3/mto_service_item_test.go | 17 ++ pkg/handlers/primeapiv3/mto_shipment_test.go | 1 + .../supportapi/move_task_order_test.go | 2 + .../supportapi/mto_service_item_test.go | 3 + pkg/handlers/supportapi/mto_shipment_test.go | 1 + pkg/models/mto_shipments.go | 4 +- .../distance_zip_lookup.go | 4 +- .../distance_zip_lookup_test.go | 4 +- .../distance_zip_sit_dest_lookup.go | 2 +- .../distance_zip_sit_dest_lookup_test.go | 1 + .../distance_zip_sit_origin_lookup.go | 2 +- .../distance_zip_sit_origin_lookup_test.go | 1 + .../service_param_value_lookups_test.go | 1 + pkg/route/dtod_planner.go | 2 +- pkg/route/dtod_planner_test.go | 4 +- pkg/route/here_planner.go | 2 +- pkg/route/hhg_planner.go | 4 +- pkg/route/hhg_planner_test.go | 8 +- pkg/route/mocks/Planner.go | 18 +- pkg/route/planner.go | 2 +- pkg/route/planner_test.go | 2 +- .../move_history/move_history_fetcher_test.go | 3 + .../move_task_order_updater_test.go | 6 + .../mto_service_item_creator.go | 10 +- .../mto_service_item_creator_test.go | 11 ++ .../mto_service_item_updater.go | 6 +- .../mto_service_item_updater_test.go | 12 ++ .../mto_shipment_address_updater.go | 4 +- .../mto_shipment_address_updater_test.go | 2 + .../mto_shipment/mto_shipment_updater.go | 14 +- .../mto_shipment/mto_shipment_updater_test.go | 3 + .../mto_shipment/shipment_approver.go | 7 +- .../mto_shipment/shipment_approver_test.go | 6 + .../mto_shipment/shipment_deleter_test.go | 2 + .../payment_request_creator_test.go | 3 + .../payment_request_recalculator_test.go | 2 + ...yment_request_shipment_recalculate_test.go | 2 + .../ppm_closeout/ppm_closeout_test.go | 4 +- .../ppmshipment/ppm_estimator_test.go | 64 ++++---- .../ppmshipment/ppm_shipment_updater_test.go | 4 +- pkg/services/reweigh/reweigh_updater_test.go | 1 + .../shipment_address_update_requester.go | 17 +- .../shipment_address_update_requester_test.go | 32 ++++ .../sit_extension/sit_extension_denier.go | 1 + pkg/testdatagen/scenario/shared.go | 28 ++-- pkg/testdatagen/testharness/make_move.go | 4 +- 64 files changed, 468 insertions(+), 142 deletions(-) delete mode 100644 migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql create mode 100644 migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 6720141b026..29248cb93ef 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1053,7 +1053,7 @@ 20241204155919_update_ordering_proc.up.sql 20241204210208_retroactive_update_of_ppm_max_and_estimated_incentives_prd.up.sql 20241210143143_redefine_mto_shipment_audit_table.up.sql -20241216190428_update_get_zip_code_function.up.sql +20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql 20241217163231_update_duty_locations_bad_zips.up.sql 20241217180136_add_AK_zips_to_zip3_distances.up.sql 20241218201833_add_PPPO_BASE_ELIZABETH.up.sql diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql deleted file mode 100644 index b5a276de591..00000000000 --- a/migrations/app/schema/20241216190428_update_get_zip_code_function.up.sql +++ /dev/null @@ -1,41 +0,0 @@ --- removing the exception that was previously being returned --- this is to avoid the db update failing for the entire proc it is used in --- we won't always have the POE/POD locations and want to ignore any errors here -CREATE OR REPLACE FUNCTION get_zip_code(shipment_id uuid, address_type VARCHAR) -RETURNS VARCHAR AS $$ - DECLARE zip_code VARCHAR; - BEGIN - - IF address_type = 'pickup' THEN - SELECT vl.uspr_zip_id - INTO zip_code - FROM mto_shipments ms - JOIN addresses a ON a.id = ms.pickup_address_id - JOIN v_locations vl ON vl.uprc_id = a.us_post_region_cities_id - WHERE ms.id = shipment_id; - ELSIF address_type = 'destination' THEN - SELECT vl.uspr_zip_id - INTO zip_code - FROM mto_shipments ms - JOIN addresses a ON a.id = ms.destination_address_id - JOIN v_locations vl ON vl.uprc_id = a.us_post_region_cities_id - WHERE ms.id = shipment_id; - ELSIF address_type = 'poe' THEN - SELECT vl.uspr_zip_id - INTO zip_code - FROM mto_service_items si - JOIN port_locations pl ON pl.id = si.poe_location_id - JOIN v_locations vl ON vl.uprc_id = pl.us_post_region_cities_id - WHERE si.mto_shipment_id = shipment_id; - ELSIF address_type = 'pod' THEN - SELECT vl.uspr_zip_id - INTO zip_code - FROM mto_service_items si - JOIN port_locations pl ON pl.id = si.pod_location_id - JOIN v_locations vl ON vl.uprc_id = pl.us_post_region_cities_id - WHERE si.mto_shipment_id = shipment_id; - END IF; - - RETURN zip_code; -END; -$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql new file mode 100644 index 00000000000..a90addbd0f7 --- /dev/null +++ b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql @@ -0,0 +1,155 @@ +-- removing the exception that was previously being returned +-- this is to avoid the db update failing for the entire proc it is used in +-- we won't always have the POE/POD locations and want to ignore any errors here +CREATE OR REPLACE FUNCTION get_zip_code(shipment_id uuid, address_type VARCHAR) +RETURNS VARCHAR AS $$ + DECLARE zip_code VARCHAR; + BEGIN + + IF address_type = 'pickup' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_shipments ms + JOIN addresses a ON a.id = ms.pickup_address_id + JOIN v_locations vl ON vl.uprc_id = a.us_post_region_cities_id + WHERE ms.id = shipment_id; + ELSIF address_type = 'destination' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_shipments ms + JOIN addresses a ON a.id = ms.destination_address_id + JOIN v_locations vl ON vl.uprc_id = a.us_post_region_cities_id + WHERE ms.id = shipment_id; + ELSIF address_type = 'poe' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_service_items si + JOIN port_locations pl ON pl.id = si.poe_location_id + JOIN v_locations vl ON vl.uprc_id = pl.us_post_region_cities_id + WHERE si.mto_shipment_id = shipment_id; + ELSIF address_type = 'pod' THEN + SELECT vl.uspr_zip_id + INTO zip_code + FROM mto_service_items si + JOIN port_locations pl ON pl.id = si.pod_location_id + JOIN v_locations vl ON vl.uprc_id = pl.us_post_region_cities_id + WHERE si.mto_shipment_id = shipment_id; + END IF; + + RETURN zip_code; +END; +$$ LANGUAGE plpgsql; + +-- updating the pricing proc to now consume the mileage we get from DTOD instead of calculate it using Rand McNally +-- this is a requirement for E-06210 +CREATE OR REPLACE PROCEDURE update_service_item_pricing( + shipment_id UUID, + mileage INT +) AS +' +DECLARE + shipment RECORD; + service_item RECORD; + escalated_price NUMERIC; + estimated_price NUMERIC; + o_rate_area_id UUID; + d_rate_area_id UUID; + contract_id UUID; + service_code TEXT; + o_zip_code TEXT; + d_zip_code TEXT; + distance NUMERIC; -- This will be replaced by mileage + estimated_fsc_multiplier NUMERIC; + fuel_price NUMERIC; + cents_above_baseline NUMERIC; + price_difference NUMERIC; +BEGIN + SELECT ms.id, ms.pickup_address_id, ms.destination_address_id, ms.requested_pickup_date, ms.prime_estimated_weight + INTO shipment + FROM mto_shipments ms + WHERE ms.id = shipment_id; + + IF shipment IS NULL THEN + RAISE EXCEPTION ''Shipment with ID % not found'', shipment_id; + END IF; + + -- exit the proc if prime_estimated_weight is NULL + IF shipment.prime_estimated_weight IS NULL THEN + RETURN; + END IF; + + -- loop through service items in the shipment + FOR service_item IN + SELECT si.id, si.re_service_id + FROM mto_service_items si + WHERE si.mto_shipment_id = shipment_id + LOOP + -- get the service code for the current service item to determine calculation + SELECT code + INTO service_code + FROM re_services + WHERE id = service_item.re_service_id; + + CASE + WHEN service_code IN (''ISLH'', ''UBP'') THEN + o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id); + d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id); + contract_id := get_contract_id(shipment.requested_pickup_date); + escalated_price := calculate_escalated_price(o_rate_area_id, d_rate_area_id, service_item.re_service_id, contract_id, service_code); + + IF shipment.prime_estimated_weight IS NOT NULL THEN + estimated_price := ROUND((escalated_price * (shipment.prime_estimated_weight / 100)::NUMERIC) * 100, 0); + RAISE NOTICE ''%: Received estimated price of % (% * (% / 100)) cents'', service_code, estimated_price, escalated_price, shipment.prime_estimated_weight; + END IF; + + WHEN service_code IN (''IHPK'', ''IUBPK'') THEN + -- perform IHPK/IUBPK-specific logic (no destination rate area) + o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id); + contract_id := get_contract_id(shipment.requested_pickup_date); + escalated_price := calculate_escalated_price(o_rate_area_id, NULL, service_item.re_service_id, contract_id, service_code); + + IF shipment.prime_estimated_weight IS NOT NULL THEN + estimated_price := ROUND((escalated_price * (shipment.prime_estimated_weight / 100)::NUMERIC) * 100, 0); + RAISE NOTICE ''%: Received estimated price of % (% * (% / 100)) cents'', service_code, estimated_price, escalated_price, shipment.prime_estimated_weight; + END IF; + + WHEN service_code IN (''IHUPK'', ''IUBUPK'') THEN + -- perform IHUPK/IUBUPK-specific logic (no origin rate area) + d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id); + contract_id := get_contract_id(shipment.requested_pickup_date); + escalated_price := calculate_escalated_price(NULL, d_rate_area_id, service_item.re_service_id, contract_id, service_code); + + IF shipment.prime_estimated_weight IS NOT NULL THEN + estimated_price := ROUND((escalated_price * (shipment.prime_estimated_weight / 100)::NUMERIC) * 100, 0); + RAISE NOTICE ''%: Received estimated price of % (% * (% / 100)) cents'', service_code, estimated_price, escalated_price, shipment.prime_estimated_weight; + END IF; + + WHEN service_code IN (''POEFSC'', ''PODFSC'') THEN + -- use the passed mileage parameter + distance := mileage; + + -- getting FSC multiplier from re_fsc_multipliers + estimated_fsc_multiplier := get_fsc_multiplier(shipment.prime_estimated_weight); + + fuel_price := get_fuel_price(shipment.requested_pickup_date); + + price_difference := calculate_price_difference(fuel_price); + + -- calculate estimated price, return as cents + IF estimated_fsc_multiplier IS NOT NULL AND distance IS NOT NULL THEN + cents_above_baseline := distance * estimated_fsc_multiplier; + RAISE NOTICE ''Distance: % * FSC Multipler: % = $% cents above baseline of $2.50'', distance, estimated_fsc_multiplier, cents_above_baseline; + RAISE NOTICE ''The fuel price is % cents above the baseline ($% - $2.50 baseline)'', price_difference, fuel_price; + estimated_price := ROUND((cents_above_baseline * price_difference) * 100); + RAISE NOTICE ''Received estimated price of % cents for service_code: %.'', estimated_price, service_code; + END IF; + END CASE; + + -- update the pricing_estimate value in mto_service_items + UPDATE mto_service_items + SET pricing_estimate = estimated_price + WHERE id = service_item.id; + END LOOP; +END; +' +LANGUAGE plpgsql; diff --git a/pkg/handlers/adminapi/moves_test.go b/pkg/handlers/adminapi/moves_test.go index 81e166a35e8..dfeabc2ee36 100644 --- a/pkg/handlers/adminapi/moves_test.go +++ b/pkg/handlers/adminapi/moves_test.go @@ -117,6 +117,7 @@ func (suite *HandlerSuite) TestUpdateMoveHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) return UpdateMoveHandler{ suite.HandlerConfig(), diff --git a/pkg/handlers/ghcapi/move_task_order_test.go b/pkg/handlers/ghcapi/move_task_order_test.go index 10e9630fc44..5668b881713 100644 --- a/pkg/handlers/ghcapi/move_task_order_test.go +++ b/pkg/handlers/ghcapi/move_task_order_test.go @@ -189,6 +189,7 @@ func (suite *HandlerSuite) TestUpdateMoveTaskOrderHandlerIntegrationSuccess() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -313,6 +314,7 @@ func (suite *HandlerSuite) TestUpdateMoveTaskOrderHandlerIntegrationWithIncomple mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -401,6 +403,7 @@ func (suite *HandlerSuite) TestUpdateMTOStatusServiceCounselingCompletedHandler( mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := UpdateMTOStatusServiceCounselingCompletedHandlerFunc{ @@ -620,6 +623,7 @@ func (suite *HandlerSuite) TestUpdateMoveTIORemarksHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/ghcapi/mto_service_items_test.go b/pkg/handlers/ghcapi/mto_service_items_test.go index b1ff7e9c405..d7b850f1bb4 100644 --- a/pkg/handlers/ghcapi/mto_service_items_test.go +++ b/pkg/handlers/ghcapi/mto_service_items_test.go @@ -312,6 +312,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -564,6 +565,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) mtoServiceItemStatusUpdater := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -625,6 +627,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) mtoServiceItemStatusUpdater := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -759,6 +762,7 @@ func (suite *HandlerSuite) TestUpdateServiceItemSitEntryDateHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) diff --git a/pkg/handlers/ghcapi/mto_shipment_test.go b/pkg/handlers/ghcapi/mto_shipment_test.go index dd60fdf7eee..712a4878a09 100644 --- a/pkg/handlers/ghcapi/mto_shipment_test.go +++ b/pkg/handlers/ghcapi/mto_shipment_test.go @@ -603,6 +603,7 @@ func (suite *HandlerSuite) TestApproveShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) approver := mtoshipment.NewShipmentApprover( mtoshipment.NewShipmentRouter(), @@ -2123,6 +2124,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2181,6 +2183,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2236,6 +2239,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2292,6 +2296,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2349,6 +2354,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2405,6 +2411,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2743,6 +2750,7 @@ func (suite *HandlerSuite) TestApproveSITExtensionHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2883,6 +2891,7 @@ func (suite *HandlerSuite) CreateApprovedSITDurationUpdate() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2966,6 +2975,7 @@ func (suite *HandlerSuite) CreateApprovedSITDurationUpdate() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -3139,6 +3149,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3223,6 +3234,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3279,6 +3291,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3331,6 +3344,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3378,6 +3392,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3462,6 +3477,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerUsingPPM() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( @@ -3673,6 +3689,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerUsingPPM() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3823,6 +3840,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerUsingPPM() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -4028,6 +4046,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -4698,6 +4717,7 @@ func (suite *HandlerSuite) TestUpdateSITServiceItemCustomerExpenseHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) updater := mtoserviceitem.NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) req := httptest.NewRequest("PATCH", fmt.Sprintf("/shipments/%s/sit-service-item/convert-to-customer-expense", approvedShipment.ID.String()), nil) @@ -4774,6 +4794,7 @@ func (suite *HandlerSuite) TestUpdateSITServiceItemCustomerExpenseHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) updater := mtoserviceitem.NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) req := httptest.NewRequest("PATCH", fmt.Sprintf("/shipments/%s/sit-service-item/convert-to-customer-expense", approvedShipment.ID.String()), nil) diff --git a/pkg/handlers/ghcapi/orders_test.go b/pkg/handlers/ghcapi/orders_test.go index 93fdc901600..4be34b50c1e 100644 --- a/pkg/handlers/ghcapi/orders_test.go +++ b/pkg/handlers/ghcapi/orders_test.go @@ -398,6 +398,7 @@ func (suite *HandlerSuite) TestUpdateOrderHandlerWithAmendedUploads() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/ghcapi/ppm_shipment_test.go b/pkg/handlers/ghcapi/ppm_shipment_test.go index b476066d53a..d2d050b8393 100644 --- a/pkg/handlers/ghcapi/ppm_shipment_test.go +++ b/pkg/handlers/ghcapi/ppm_shipment_test.go @@ -388,7 +388,7 @@ func (suite *HandlerSuite) TestGetPPMSITEstimatedCostHandler() { ppmShipment.DestinationAddress = destinationAddress mockedPlanner := &routemocks.Planner{} mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813").Return(2294, nil) + "90210", "30813", false).Return(2294, nil) }) setUpGetCostRequestAndParams := func() ppmsitops.GetPPMSITEstimatedCostParams { diff --git a/pkg/handlers/internalapi/mto_shipment_test.go b/pkg/handlers/internalapi/mto_shipment_test.go index 4d2b557286f..3e43ee91955 100644 --- a/pkg/handlers/internalapi/mto_shipment_test.go +++ b/pkg/handlers/internalapi/mto_shipment_test.go @@ -77,6 +77,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerV1() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapi/move_task_order_test.go b/pkg/handlers/primeapi/move_task_order_test.go index 2bfa5abfbcc..5f79f53584e 100644 --- a/pkg/handlers/primeapi/move_task_order_test.go +++ b/pkg/handlers/primeapi/move_task_order_test.go @@ -1710,6 +1710,7 @@ func (suite *HandlerSuite) TestUpdateMTOPostCounselingInfo() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -1794,6 +1795,7 @@ func (suite *HandlerSuite) TestUpdateMTOPostCounselingInfo() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapi/mto_service_item_test.go b/pkg/handlers/primeapi/mto_service_item_test.go index 196a4c0b860..8ad036e79fa 100644 --- a/pkg/handlers/primeapi/mto_service_item_test.go +++ b/pkg/handlers/primeapi/mto_service_item_test.go @@ -94,6 +94,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -152,6 +153,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -290,6 +292,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -334,6 +337,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -485,6 +489,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -522,6 +527,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -645,6 +651,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -691,6 +698,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -760,6 +768,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -844,6 +853,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITNoA mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -954,6 +964,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITWit mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1127,6 +1138,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1201,6 +1213,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1234,6 +1247,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1290,6 +1304,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1344,6 +1359,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1542,6 +1558,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemDDDSIT() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) subtestData.handler = UpdateMTOServiceItemHandler{ suite.HandlerConfig(), @@ -1825,6 +1842,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemDOPSIT() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) subtestData.handler = UpdateMTOServiceItemHandler{ suite.HandlerConfig(), diff --git a/pkg/handlers/primeapi/mto_shipment_address_test.go b/pkg/handlers/primeapi/mto_shipment_address_test.go index 8a45daa4156..71235074946 100644 --- a/pkg/handlers/primeapi/mto_shipment_address_test.go +++ b/pkg/handlers/primeapi/mto_shipment_address_test.go @@ -47,6 +47,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentAddressHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) // Create handler handler := UpdateMTOShipmentAddressHandler{ diff --git a/pkg/handlers/primeapi/mto_shipment_test.go b/pkg/handlers/primeapi/mto_shipment_test.go index 5b602de7873..4581aa59487 100644 --- a/pkg/handlers/primeapi/mto_shipment_test.go +++ b/pkg/handlers/primeapi/mto_shipment_test.go @@ -203,6 +203,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentStatusHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() addressUpdater := address.NewAddressUpdater() @@ -223,6 +224,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentStatusHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) handler := UpdateMTOShipmentStatusHandler{ handlerConfig, @@ -414,6 +416,7 @@ func (suite *HandlerSuite) TestDeleteMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapi/payment_request_test.go b/pkg/handlers/primeapi/payment_request_test.go index fd4e8dd14da..1195c3f7750 100644 --- a/pkg/handlers/primeapi/payment_request_test.go +++ b/pkg/handlers/primeapi/payment_request_test.go @@ -746,6 +746,7 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerNewPaymentRequestCreat mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", + false, ).Return(defaultZipDistance, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( @@ -905,6 +906,7 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerInvalidMTOReferenceID( mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", + false, ).Return(defaultZipDistance, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( @@ -970,6 +972,7 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerInvalidMTOReferenceID( mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", + false, ).Return(defaultZipDistance, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( diff --git a/pkg/handlers/primeapi/reweigh_test.go b/pkg/handlers/primeapi/reweigh_test.go index baa363a5d8a..6603dcb1c68 100644 --- a/pkg/handlers/primeapi/reweigh_test.go +++ b/pkg/handlers/primeapi/reweigh_test.go @@ -36,6 +36,7 @@ func (suite *HandlerSuite) TestUpdateReweighHandler() { mockPlanner.On("ZipTransitDistance", recalculateTestPickupZip, recalculateTestDestinationZip, + false, ).Return(recalculateTestZip3Distance, nil) // Get shipment payment request recalculator service diff --git a/pkg/handlers/primeapiv2/mto_service_item_test.go b/pkg/handlers/primeapiv2/mto_service_item_test.go index ffe960ba4f4..8fc984d4daa 100644 --- a/pkg/handlers/primeapiv2/mto_service_item_test.go +++ b/pkg/handlers/primeapiv2/mto_service_item_test.go @@ -88,6 +88,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -146,6 +147,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -284,6 +286,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -328,6 +331,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -479,6 +483,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -516,6 +521,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -639,6 +645,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -685,6 +692,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -754,6 +762,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -838,6 +847,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITNoA mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -946,6 +956,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITWit mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1113,6 +1124,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1187,6 +1199,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1220,6 +1233,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1276,6 +1290,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1340,6 +1355,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ diff --git a/pkg/handlers/primeapiv2/mto_shipment_test.go b/pkg/handlers/primeapiv2/mto_shipment_test.go index 314dc9c3a5f..83134e3b522 100644 --- a/pkg/handlers/primeapiv2/mto_shipment_test.go +++ b/pkg/handlers/primeapiv2/mto_shipment_test.go @@ -52,6 +52,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapiv3/mto_service_item_test.go b/pkg/handlers/primeapiv3/mto_service_item_test.go index 1bc9362127c..7ea19fef6f3 100644 --- a/pkg/handlers/primeapiv3/mto_service_item_test.go +++ b/pkg/handlers/primeapiv3/mto_service_item_test.go @@ -87,6 +87,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) subtestData := makeSubtestData() moveRouter := moverouter.NewMoveRouter() @@ -147,6 +148,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -285,6 +287,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -329,6 +332,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -480,6 +484,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -517,6 +522,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -640,6 +646,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -686,6 +693,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -755,6 +763,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -839,6 +848,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITNoA mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -947,6 +957,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITWit mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1114,6 +1125,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1188,6 +1200,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1221,6 +1234,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1277,6 +1291,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1341,6 +1356,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1377,6 +1393,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ diff --git a/pkg/handlers/primeapiv3/mto_shipment_test.go b/pkg/handlers/primeapiv3/mto_shipment_test.go index 44c8f229e0d..83f71196d6b 100644 --- a/pkg/handlers/primeapiv3/mto_shipment_test.go +++ b/pkg/handlers/primeapiv3/mto_shipment_test.go @@ -58,6 +58,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/supportapi/move_task_order_test.go b/pkg/handlers/supportapi/move_task_order_test.go index f10fde1438e..1c219d99a70 100644 --- a/pkg/handlers/supportapi/move_task_order_test.go +++ b/pkg/handlers/supportapi/move_task_order_test.go @@ -173,6 +173,7 @@ func (suite *HandlerSuite) TestMakeMoveAvailableHandlerIntegrationSuccess() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -388,6 +389,7 @@ func (suite *HandlerSuite) TestCreateMoveTaskOrderRequestHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/supportapi/mto_service_item_test.go b/pkg/handlers/supportapi/mto_service_item_test.go index 9b2a995255a..0e3faa635cd 100644 --- a/pkg/handlers/supportapi/mto_service_item_test.go +++ b/pkg/handlers/supportapi/mto_service_item_test.go @@ -85,6 +85,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandlerApproveSuccess() mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) handler := UpdateMTOServiceItemStatusHandler{handlerConfig, mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher), @@ -142,6 +143,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandlerRejectSuccess() mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) handler := UpdateMTOServiceItemStatusHandler{handlerConfig, mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher), @@ -199,6 +201,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandlerRejectionFailedN mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) handler := UpdateMTOServiceItemStatusHandler{handlerConfig, mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher), diff --git a/pkg/handlers/supportapi/mto_shipment_test.go b/pkg/handlers/supportapi/mto_shipment_test.go index c1a9bb7018b..1a12aff8ced 100644 --- a/pkg/handlers/supportapi/mto_shipment_test.go +++ b/pkg/handlers/supportapi/mto_shipment_test.go @@ -97,6 +97,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentStatusHandler() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) planner.On("Zip5TransitDistanceLineHaul", diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index da5e021a698..7a6d386f945 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -373,8 +373,8 @@ func CreateApprovedServiceItemsForShipment(db *pop.Connection, shipment *MTOShip // a db stored proc that will handle updating the pricing_estimate columns of basic service items for shipment types: // iHHG // iUB -func UpdateEstimatedPricingForShipmentBasicServiceItems(db *pop.Connection, shipment *MTOShipment) error { - err := db.RawQuery("CALL update_service_item_pricing($1)", shipment.ID).Exec() +func UpdateEstimatedPricingForShipmentBasicServiceItems(db *pop.Connection, shipment *MTOShipment, mileage int) error { + err := db.RawQuery("CALL update_service_item_pricing($1, $2)", shipment.ID, mileage).Exec() if err != nil { return fmt.Errorf("error updating estimated pricing for shipment's service items: %w", err) } diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go index be5f2515e49..98cbb647775 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go @@ -83,7 +83,7 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service } if mtoShipment.DeliveryAddressUpdate != nil && mtoShipment.DeliveryAddressUpdate.Status == models.ShipmentAddressUpdateStatusApproved { - distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, mtoShipment.DeliveryAddressUpdate.NewAddress.PostalCode) + distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, mtoShipment.DeliveryAddressUpdate.NewAddress.PostalCode, false) if err != nil { return "", err } @@ -98,7 +98,7 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service if pickupZip == destinationZip { distanceMiles = 1 } else { - distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip) + distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false) if err != nil { return "", err } diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go index 4f826c52009..4168c42bd37 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go @@ -79,7 +79,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() { suite.NoError(err) planner := suite.planner.(*mocks.Planner) - planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode) + planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode, false) err = suite.DB().Reload(&ppmShipment.Shipment) suite.NoError(err) @@ -110,7 +110,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() { suite.NoError(err) planner := suite.planner.(*mocks.Planner) - planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode) + planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode, false) err = suite.DB().Reload(&ppmShipment.Shipment) suite.NoError(err) diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go index 2136d7556bc..bc3e612c811 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go @@ -33,7 +33,7 @@ func (r DistanceZipSITDestLookup) lookup(appCtx appcontext.AppContext, keyData * if destZip == finalDestZip { distanceMiles = 1 } else { - distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, destZip, finalDestZip) + distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, destZip, finalDestZip, false) } if distanceErr != nil { diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go index 8231238b831..c0e29027758 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go @@ -211,6 +211,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceZipSITDestLookup() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(0, errors.New("error with ZipTransitDistance")) paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), errorPlanner, mtoServiceItemSameZip3, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go index e452adbed10..945462236dd 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go @@ -39,7 +39,7 @@ func (r DistanceZipSITOriginLookup) lookup(appCtx appcontext.AppContext, keyData if originZip == actualOriginZip { distanceMiles = 1 } else { - distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, originZip, actualOriginZip) + distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, originZip, actualOriginZip, false) } if distanceErr != nil { return "", distanceErr diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go index 31d766db385..eabf098155f 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go @@ -184,6 +184,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceZipSITOriginLookup() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(0, errors.New("error with ZipTransitDistance")) paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), errorPlanner, mtoServiceItemSameZip3, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) diff --git a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go index bc5587b7941..01767a6591b 100644 --- a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go +++ b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go @@ -46,6 +46,7 @@ func TestServiceParamValueLookupsSuite(t *testing.T) { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(defaultZipDistance, nil) ts := &ServiceParamValueLookupsSuite{ diff --git a/pkg/route/dtod_planner.go b/pkg/route/dtod_planner.go index 383de1dd923..b8391c70bbb 100644 --- a/pkg/route/dtod_planner.go +++ b/pkg/route/dtod_planner.go @@ -44,7 +44,7 @@ func (p *dtodPlanner) Zip3TransitDistance(_ appcontext.AppContext, _ string, _ s } // ZipTransitDistance calculates the distance between two valid Zips -func (p *dtodPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) { +func (p *dtodPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) { if len(source) < 5 { source = fmt.Sprintf("%05s", source) } diff --git a/pkg/route/dtod_planner_test.go b/pkg/route/dtod_planner_test.go index c8978eea831..9f419401e7e 100644 --- a/pkg/route/dtod_planner_test.go +++ b/pkg/route/dtod_planner_test.go @@ -111,7 +111,7 @@ func (suite *GHCTestSuite) TestDTODZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewDTODPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301") + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false) suite.NoError(err) suite.Equal(150, distance) }) @@ -125,7 +125,7 @@ func (suite *GHCTestSuite) TestDTODZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewDTODPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901") + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901", false) suite.Error(err) suite.Equal(0, distance) }) diff --git a/pkg/route/here_planner.go b/pkg/route/here_planner.go index e8d40c85521..aea2b861639 100644 --- a/pkg/route/here_planner.go +++ b/pkg/route/here_planner.go @@ -219,7 +219,7 @@ func (p *herePlanner) Zip5TransitDistance(appCtx appcontext.AppContext, source s } // ZipTransitDistance calculates the distance between two valid Zip5s; it is used by the PPM flow -func (p *herePlanner) ZipTransitDistance(_ appcontext.AppContext, _ string, _ string) (int, error) { +func (p *herePlanner) ZipTransitDistance(_ appcontext.AppContext, _ string, _ string, _ bool) (int, error) { // This might get retired after we transition over fully to GHC. panic("implement me") diff --git a/pkg/route/hhg_planner.go b/pkg/route/hhg_planner.go index 544d8f5eed7..5f9fa3f7044 100644 --- a/pkg/route/hhg_planner.go +++ b/pkg/route/hhg_planner.go @@ -46,7 +46,7 @@ func (p *hhgPlanner) Zip3TransitDistance(_ appcontext.AppContext, _ string, _ st } // ZipTransitDistance calculates the distance between two valid Zips -func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) { +func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) { sourceZip5 := source if len(source) < 5 { sourceZip5 = fmt.Sprintf("%05s", source) @@ -58,7 +58,7 @@ func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source str sourceZip3 := sourceZip5[0:3] destZip3 := destZip5[0:3] - if sourceZip3 == destZip3 { + if sourceZip3 == destZip3 || useDTOD { if sourceZip5 == destZip5 { return 1, nil } diff --git a/pkg/route/hhg_planner_test.go b/pkg/route/hhg_planner_test.go index e443788fd28..ba16a28d019 100644 --- a/pkg/route/hhg_planner_test.go +++ b/pkg/route/hhg_planner_test.go @@ -89,7 +89,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301") + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false) suite.NoError(err) suite.Equal(150, distance) }) @@ -99,7 +99,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "11201", "11201") + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "11201", "11201", false) suite.NoError(err) suite.Equal(1, distance) }) @@ -135,7 +135,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { planner := NewHHGPlanner(plannerMileage) // Get distance between two zips in the same base point city - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "33169", "33040") + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "33169", "33040", false) suite.NoError(err) // Ensure DTOD was used for distance @@ -151,7 +151,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901") + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901", false) suite.Error(err) suite.Equal(0, distance) }) diff --git a/pkg/route/mocks/Planner.go b/pkg/route/mocks/Planner.go index 2cf26622df2..bbbe8cf7787 100644 --- a/pkg/route/mocks/Planner.go +++ b/pkg/route/mocks/Planner.go @@ -156,9 +156,9 @@ func (_m *Planner) Zip5TransitDistanceLineHaul(appCtx appcontext.AppContext, sou return r0, r1 } -// ZipTransitDistance provides a mock function with given fields: appCtx, source, destination -func (_m *Planner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) { - ret := _m.Called(appCtx, source, destination) +// ZipTransitDistance provides a mock function with given fields: appCtx, source, destination, useDTOD +func (_m *Planner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) { + ret := _m.Called(appCtx, source, destination, useDTOD) if len(ret) == 0 { panic("no return value specified for ZipTransitDistance") @@ -166,17 +166,17 @@ func (_m *Planner) ZipTransitDistance(appCtx appcontext.AppContext, source strin var r0 int var r1 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string) (int, error)); ok { - return rf(appCtx, source, destination) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string, bool) (int, error)); ok { + return rf(appCtx, source, destination, useDTOD) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string) int); ok { - r0 = rf(appCtx, source, destination) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string, bool) int); ok { + r0 = rf(appCtx, source, destination, useDTOD) } else { r0 = ret.Get(0).(int) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, string) error); ok { - r1 = rf(appCtx, source, destination) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, string, bool) error); ok { + r1 = rf(appCtx, source, destination, useDTOD) } else { r1 = ret.Error(1) } diff --git a/pkg/route/planner.go b/pkg/route/planner.go index ccc349be6d9..1b6c808c23f 100644 --- a/pkg/route/planner.go +++ b/pkg/route/planner.go @@ -120,7 +120,7 @@ type Planner interface { // Zip5TransitDistanceLineHaul is used by PPM flow and checks for minimum distance restriction as PPM doesn't allow short hauls // New code should probably make the minimum checks after calling Zip5TransitDistance over using this method Zip5TransitDistanceLineHaul(appCtx appcontext.AppContext, source string, destination string) (int, error) - ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) + ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) Zip3TransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) Zip5TransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) } diff --git a/pkg/route/planner_test.go b/pkg/route/planner_test.go index eb574873278..cfbd39dd69f 100644 --- a/pkg/route/planner_test.go +++ b/pkg/route/planner_test.go @@ -109,7 +109,7 @@ func (suite *PlannerFullSuite) TestZipDistance() { {zip1: "902101234", zip2: caZip, distanceMin: 30, distanceMax: 49}, } for _, ts := range tests { - distance, err := suite.planner.ZipTransitDistance(suite.AppContextForTest(), ts.zip1, ts.zip2) + distance, err := suite.planner.ZipTransitDistance(suite.AppContextForTest(), ts.zip1, ts.zip2, false) if len(ts.zip1) > 5 { suite.Error(err) suite.Equal(distance, 0) diff --git a/pkg/services/move_history/move_history_fetcher_test.go b/pkg/services/move_history/move_history_fetcher_test.go index af89aee3bff..b3b89e7ed99 100644 --- a/pkg/services/move_history/move_history_fetcher_test.go +++ b/pkg/services/move_history/move_history_fetcher_test.go @@ -375,6 +375,7 @@ func (suite *MoveHistoryServiceSuite) TestMoveHistoryFetcherScenarios() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) updater := mtoserviceitem.NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) @@ -550,6 +551,7 @@ func (suite *MoveHistoryServiceSuite) TestMoveHistoryFetcherScenarios() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -623,6 +625,7 @@ func (suite *MoveHistoryServiceSuite) TestMoveHistoryFetcherScenarios() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) 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..8af2f105f66 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 @@ -59,6 +59,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdateStatusSer mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) mtoUpdater := mt.NewMoveTaskOrderUpdater( queryBuilder, @@ -346,6 +347,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdatePostCouns mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -513,6 +515,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_ShowHide() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -754,6 +757,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_MakeAvailableTo mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, 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) @@ -792,6 +796,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_MakeAvailableTo mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, 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) @@ -1041,6 +1046,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdatePPMType() mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { 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 2ab0802badd..a92febd28e8 100644 --- a/pkg/services/mto_service_item/mto_service_item_creator.go +++ b/pkg/services/mto_service_item/mto_service_item_creator.go @@ -128,7 +128,7 @@ func (o *mtoServiceItemCreator) findEstimatedPrice(appCtx appcontext.AppContext, return 0, err } if mtoShipment.PickupAddress != nil && mtoShipment.DestinationAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false) if err != nil { return 0, err } @@ -144,7 +144,7 @@ func (o *mtoServiceItemCreator) findEstimatedPrice(appCtx appcontext.AppContext, return 0, err } if mtoShipment.PickupAddress != nil && mtoShipment.DestinationAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false) if err != nil { return 0, err } @@ -167,7 +167,7 @@ func (o *mtoServiceItemCreator) findEstimatedPrice(appCtx appcontext.AppContext, } if mtoShipment.PickupAddress != nil && mtoShipment.DestinationAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false) if err != nil { return 0, err } @@ -303,14 +303,14 @@ func (o *mtoServiceItemCreator) calculateSITDeliveryMiles(appCtx appcontext.AppC originalSITAddressZip = mtoShipment.PickupAddress.PostalCode } if mtoShipment.PickupAddress != nil && originalSITAddressZip != "" { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, originalSITAddressZip) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, originalSITAddressZip, false) } } if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || serviceItem.ReService.Code == models.ReServiceCodeDDASIT || serviceItem.ReService.Code == models.ReServiceCodeDDSFSC || serviceItem.ReService.Code == models.ReServiceCodeDDDSIT { // Creation: Destination SIT: distance between shipment destination address & service item destination address if mtoShipment.DestinationAddress != nil && serviceItem.SITDestinationFinalAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationFinalAddress.PostalCode) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationFinalAddress.PostalCode, false) } } if err != nil { 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 e9799db0278..619be14b026 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 @@ -193,6 +193,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateMTOServiceItemWithInvalidMove mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) serviceItemForUnapprovedMove := suite.buildValidServiceItemWithInvalidMove() @@ -221,6 +222,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateMTOServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1031,6 +1033,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1080,6 +1083,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1154,6 +1158,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1280,6 +1285,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1314,6 +1320,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1347,6 +1354,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1422,6 +1430,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItemFailToCre mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1456,6 +1465,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateDestSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1755,6 +1765,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateDestSITServiceItem() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) createdServiceItems, _, err := creator.CreateMTOServiceItem(suite.AppContextForTest(), &serviceItemDDASIT) 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 9ffb413c26d..5cf23590cd7 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -244,7 +244,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, if serviceItem.ReService.Code == models.ReServiceCodeDDDSIT || serviceItem.ReService.Code == models.ReServiceCodeDDSFSC { // Destination SIT: distance between shipment destination address & service item ORIGINAL destination address - milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode) + milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) if err != nil { return nil, err } @@ -256,7 +256,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, if serviceItem.ReService.Code == models.ReServiceCodeDOPSIT || serviceItem.ReService.Code == models.ReServiceCodeDOSFSC { // Origin SIT: distance between shipment pickup address & service item ORIGINAL pickup address - milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode) + milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false) if err != nil { return nil, err } @@ -384,7 +384,7 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItemPrime( func calculateOriginSITRequiredDeliveryDate(appCtx appcontext.AppContext, shipment models.MTOShipment, planner route.Planner, sitCustomerContacted *time.Time, sitDepartureDate *time.Time) (*time.Time, error) { // Get a distance calculation between pickup and destination addresses. - distance, err := planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode) + distance, err := planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, false) if err != nil { return nil, apperror.NewUnprocessableEntityError("cannot calculate distance between pickup and destination addresses") 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 2f6a52310ea..d33bf218ab1 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 @@ -49,6 +49,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) updater := NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -326,6 +327,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -450,6 +452,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -578,6 +581,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -704,6 +708,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -780,6 +785,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -850,6 +856,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -958,6 +965,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1073,6 +1081,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1233,6 +1242,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1343,6 +1353,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1234, apperror.UnprocessableEntityError{}) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1959,6 +1970,7 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) updater := NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) diff --git a/pkg/services/mto_shipment/mto_shipment_address_updater.go b/pkg/services/mto_shipment/mto_shipment_address_updater.go index edab362940f..4b6efc1d478 100644 --- a/pkg/services/mto_shipment/mto_shipment_address_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_address_updater.go @@ -72,9 +72,9 @@ func UpdateOriginSITServiceItemSITDeliveryMiles(planner route.Planner, shipment // Origin SIT: distance between shipment pickup address & service item ORIGINAL pickup address if serviceItem.SITOriginHHGOriginalAddress != nil { - milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode) + milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false) } else { - milesCalculated, err = planner.ZipTransitDistance(appCtx, oldAddress.PostalCode, newAddress.PostalCode) + milesCalculated, err = planner.ZipTransitDistance(appCtx, oldAddress.PostalCode, newAddress.PostalCode, false) } if err != nil { return nil, err diff --git a/pkg/services/mto_shipment/mto_shipment_address_updater_test.go b/pkg/services/mto_shipment/mto_shipment_address_updater_test.go index 44c773ef06f..2e81afcecfb 100644 --- a/pkg/services/mto_shipment/mto_shipment_address_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_address_updater_test.go @@ -19,6 +19,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateMTOShipmentAddress() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) addressCreator := address.NewAddressCreator() addressUpdater := address.NewAddressUpdater() @@ -169,6 +170,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateMTOShipmentAddress() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(465, nil) mtoServiceItems, _ := UpdateOriginSITServiceItemSITDeliveryMiles(planner, &externalShipment, &newAddress, &oldAddress, suite.AppContextForTest()) suite.Equal(2, len(*mtoServiceItems)) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 5c03fb11f71..61d61e386ee 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -860,8 +860,14 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { + // the db proc consumes the mileage needed, so we need to get that first + mileage, err := f.planner.ZipTransitDistance(appCtx, newShipment.PickupAddress.PostalCode, newShipment.DestinationAddress.PostalCode, true) + if err != nil { + return err + } + // Update the service item pricing if relevant fields have changed - err := models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment) + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment, mileage) if err != nil { return err } @@ -1174,7 +1180,7 @@ func CalculateRequiredDeliveryDate(appCtx appcontext.AppContext, planner route.P "99950", "99824", "99850", "99901", "99928", "99950", "99835"} // Get a distance calculation between pickup and destination addresses. - distance, err := planner.ZipTransitDistance(appCtx, pickupAddress.PostalCode, destinationAddress.PostalCode) + distance, err := planner.ZipTransitDistance(appCtx, pickupAddress.PostalCode, destinationAddress.PostalCode, false) if err != nil { return nil, err } @@ -1325,11 +1331,11 @@ func UpdateDestinationSITServiceItemsSITDeliveryMiles(planner route.Planner, app if TOOApprovalRequired { if serviceItem.SITDestinationOriginalAddress != nil { // if TOO approval was required, shipment destination address has been updated at this point - milesCalculated, err = planner.ZipTransitDistance(appCtx, shipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode) + milesCalculated, err = planner.ZipTransitDistance(appCtx, shipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) } } else { // if TOO approval was not required, use the newAddress - milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode) + milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) } if err != nil { return err diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index aabab4f1a16..fab08803ece 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -50,6 +50,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(1000, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(NewShipmentReweighRequester()) @@ -1795,6 +1796,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateMTOShipmentStatus() { mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), mock.AnythingOfType("string"), + false, ).Return(500, nil).Run(func(args mock.Arguments) { TransitDistancePickupArg = args.Get(1).(string) TransitDistanceDestinationArg = args.Get(2).(string) @@ -2949,6 +2951,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateStatusServiceItems() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).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) diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index 161dde3b721..01d92bcb179 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -98,7 +98,12 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen // Update the service item pricing if we have the estimated weight if shipment.PrimeEstimatedWeight != nil { - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment) + mileage, err := f.planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, true) + if err != nil { + return err + } + + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment, mileage) if err != nil { return err } diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 943cd4edb72..5902d863901 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -91,6 +91,7 @@ func (suite *MTOShipmentServiceSuite) createApproveShipmentSubtestData() (subtes mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) subtestData.planner = &mocks.Planner{} @@ -287,6 +288,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(500, nil) preApprovalTime := time.Now() @@ -406,6 +408,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("*appcontext.appContext"), createdShipment.PickupAddress.PostalCode, createdShipment.DestinationAddress.PostalCode, + false, ).Return(500, nil) shipmentHeavyEtag := etag.GenerateEtag(shipmentHeavy.UpdatedAt) @@ -681,6 +684,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), mock.AnythingOfType("string"), + false, ).Return(500, nil).Run(func(args mock.Arguments) { TransitDistancePickupArg = args.Get(1).(string) TransitDistanceDestinationArg = args.Get(2).(string) @@ -735,6 +739,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), mock.AnythingOfType("string"), + false, ).Return(500, nil) suite.Equal(8000, *shipment.MoveTaskOrder.Orders.Entitlement.AuthorizedWeight()) @@ -775,6 +780,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), mock.AnythingOfType("string"), + false, ).Return(500, nil) shipmentEtag := etag.GenerateEtag(shipment.UpdatedAt) diff --git a/pkg/services/mto_shipment/shipment_deleter_test.go b/pkg/services/mto_shipment/shipment_deleter_test.go index 1e0ca2796f6..6a0d900c128 100644 --- a/pkg/services/mto_shipment/shipment_deleter_test.go +++ b/pkg/services/mto_shipment/shipment_deleter_test.go @@ -29,6 +29,7 @@ func (suite *MTOShipmentServiceSuite) TestShipmentDeleter() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -259,6 +260,7 @@ func (suite *MTOShipmentServiceSuite) TestPrimeShipmentDeleter() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/services/payment_request/payment_request_creator_test.go b/pkg/services/payment_request/payment_request_creator_test.go index 61edc1c6fa8..09b41de1ca7 100644 --- a/pkg/services/payment_request/payment_request_creator_test.go +++ b/pkg/services/payment_request/payment_request_creator_test.go @@ -327,6 +327,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequest() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(0, nil) }) @@ -568,6 +569,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequest() { mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(0, nil) failingCreator := NewPaymentRequestCreator(planner, failingServiceItemPricer) @@ -1459,6 +1461,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequestCheckOnNTSRelea mock.AnythingOfType("*appcontext.appContext"), testStorageFacilityZip, testDestinationZip, + false, ).Return(testZip3Distance, nil) // Create an initial payment request. diff --git a/pkg/services/payment_request/payment_request_recalculator_test.go b/pkg/services/payment_request/payment_request_recalculator_test.go index 4a91e7f9a10..4ca7922e884 100644 --- a/pkg/services/payment_request/payment_request_recalculator_test.go +++ b/pkg/services/payment_request/payment_request_recalculator_test.go @@ -55,6 +55,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() mock.AnythingOfType("*appcontext.appContext"), recalculateTestPickupZip, recalculateTestDestinationZip, + false, ).Return(recalculateTestZip3Distance, nil) // Create an initial payment request. @@ -295,6 +296,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestErrors() { mock.AnythingOfType("*appcontext.appContext"), recalculateTestPickupZip, recalculateTestDestinationZip, + false, ).Return(recalculateTestZip3Distance, nil) // Create an initial payment request. diff --git a/pkg/services/payment_request/payment_request_shipment_recalculate_test.go b/pkg/services/payment_request/payment_request_shipment_recalculate_test.go index 238a622bc90..d308e237efb 100644 --- a/pkg/services/payment_request/payment_request_shipment_recalculate_test.go +++ b/pkg/services/payment_request/payment_request_shipment_recalculate_test.go @@ -27,6 +27,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculateShipmentPaymentRequestSu mock.AnythingOfType("*appcontext.appContext"), recalculateTestPickupZip, recalculateTestDestinationZip, + false, ).Return(recalculateTestZip3Distance, nil) // Create an initial payment request. @@ -136,6 +137,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculateShipmentPaymentRequestEr mock.AnythingOfType("*appcontext.appContext"), recalculateTestPickupZip, recalculateTestDestinationZip, + false, ).Return(recalculateTestZip3Distance, nil) creator := NewPaymentRequestCreator(mockPlanner, ghcrateengine.NewServiceItemPricer()) diff --git a/pkg/services/ppm_closeout/ppm_closeout_test.go b/pkg/services/ppm_closeout/ppm_closeout_test.go index 2564a06b468..0942215fa7c 100644 --- a/pkg/services/ppm_closeout/ppm_closeout_test.go +++ b/pkg/services/ppm_closeout/ppm_closeout_test.go @@ -348,7 +348,7 @@ func (suite *PPMCloseoutSuite) TestPPMShipmentCreator() { appCtx := suite.AppContextForTest() mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) mockedPaymentRequestHelper.On( "FetchServiceParamsForServiceItems", @@ -404,7 +404,7 @@ func (suite *PPMCloseoutSuite) TestPPMShipmentCreator() { appCtx := suite.AppContextForTest() mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) mockedPaymentRequestHelper.On( "FetchServiceParamsForServiceItems", diff --git a/pkg/services/ppmshipment/ppm_estimator_test.go b/pkg/services/ppmshipment/ppm_estimator_test.go index 4826d396a33..fb8a8adff2b 100644 --- a/pkg/services/ppmshipment/ppm_estimator_test.go +++ b/pkg/services/ppmshipment/ppm_estimator_test.go @@ -492,13 +492,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) linehaul, fuel, origin, dest, packing, unpacking, _, err := ppmEstimator.PriceBreakdown(suite.AppContextForTest(), &ppmShipment) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(unit.Pound(4000), *ppmShipment.EstimatedWeight) @@ -537,13 +537,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -574,13 +574,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -608,13 +608,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -642,13 +642,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -678,7 +678,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil).Once() + "50309", "30813", false).Return(2294, nil).Once() ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) @@ -764,13 +764,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { mock.AnythingOfType("[]models.MTOServiceItem")).Return(serviceParams, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) maxIncentive, err := ppmEstimator.MaxIncentive(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(unit.Cents(112102682), *maxIncentive) @@ -825,13 +825,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -876,12 +876,12 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { mock.AnythingOfType("[]models.MTOServiceItem")).Return(serviceParams, nil) // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles - mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813").Return(2294, nil) + mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) - mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813") + mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -927,12 +927,12 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmFinalIncentiveLimitedByAllowableWeight, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) - mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813") + mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -982,13 +982,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -1039,13 +1039,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) @@ -1101,13 +1101,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) @@ -1171,13 +1171,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813") + "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) @@ -1666,7 +1666,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { }, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) _, estimatedSITCost, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), models.PPMShipment{}, &shipmentOriginSIT) @@ -1728,7 +1728,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { }, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) _, estimatedSITCost, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), models.PPMShipment{}, &shipmentDestinationSIT) @@ -1790,7 +1790,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { }, }, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813").Return(2294, nil) + "50309", "30813", false).Return(2294, nil) _, estimatedSITCost, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), models.PPMShipment{}, &shipmentOriginSIT) @@ -1980,10 +1980,10 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { shipmentDifferentDeparture.ExpectedDepartureDate = originalShipment.ExpectedDepartureDate.Add(time.Hour * 24 * 70) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90211", "30813").Return(2294, nil) + "90211", "30813", false).Return(2294, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30814").Return(2290, nil) + "50309", "30814", false).Return(2290, nil) // SIT specific field changes will likely cause the price to change, although adjusting dates may not change // the total number of days in SIT. diff --git a/pkg/services/ppmshipment/ppm_shipment_updater_test.go b/pkg/services/ppmshipment/ppm_shipment_updater_test.go index 8d21e74baf6..3ee017878b4 100644 --- a/pkg/services/ppmshipment/ppm_shipment_updater_test.go +++ b/pkg/services/ppmshipment/ppm_shipment_updater_test.go @@ -1504,7 +1504,7 @@ func (suite *PPMShipmentSuite) TestUpdatePPMShipment() { originalPPM.DestinationAddress = destinationAddress mockedPlanner := &routemocks.Planner{} mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813").Return(2294, nil) + "90210", "30813", false).Return(2294, nil) updatedPPM, err := subtestData.ppmShipmentUpdater.UpdatePPMShipmentSITEstimatedCost(appCtx, &originalPPM) @@ -1560,7 +1560,7 @@ func (suite *PPMShipmentSuite) TestUpdatePPMShipment() { originalPPM.DestinationAddress = destinationAddress mockedPlanner := &routemocks.Planner{} mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813").Return(2294, nil) + "90210", "30813", false).Return(2294, nil) updatedPPM, err := subtestData.ppmShipmentUpdater.UpdatePPMShipmentSITEstimatedCost(appCtx, &originalPPM) diff --git a/pkg/services/reweigh/reweigh_updater_test.go b/pkg/services/reweigh/reweigh_updater_test.go index ad2ab0da981..c1501906a98 100644 --- a/pkg/services/reweigh/reweigh_updater_test.go +++ b/pkg/services/reweigh/reweigh_updater_test.go @@ -31,6 +31,7 @@ func (suite *ReweighSuite) TestReweighUpdater() { mockPlanner.On("ZipTransitDistance", recalculateTestPickupZip, recalculateTestDestinationZip, + false, ).Return(recalculateTestZip3Distance, nil) // Get shipment payment request recalculator service diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index 57d608e255b..e4e9d426ddf 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -41,7 +41,7 @@ func NewShipmentAddressUpdateRequester(planner route.Planner, addressCreator ser func (f *shipmentAddressUpdateRequester) isAddressChangeDistanceOver50(appCtx appcontext.AppContext, addressUpdate models.ShipmentAddressUpdate) (bool, error) { //We calculate and set the distance between the old and new address - distance, err := f.planner.ZipTransitDistance(appCtx, addressUpdate.OriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode) + distance, err := f.planner.ZipTransitDistance(appCtx, addressUpdate.OriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode, false) if err != nil { return false, err } @@ -92,11 +92,11 @@ func (f *shipmentAddressUpdateRequester) doesDeliveryAddressUpdateChangeMileageB return false, nil } - previousDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, originalDeliveryAddress.PostalCode) + previousDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, originalDeliveryAddress.PostalCode, false) if err != nil { return false, err } - newDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, newDeliveryAddress.PostalCode) + newDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, newDeliveryAddress.PostalCode, false) if err != nil { return false, err } @@ -308,14 +308,14 @@ func (f *shipmentAddressUpdateRequester) RequestShipmentDeliveryAddressUpdate(ap if addressUpdate.NewSitDistanceBetween != nil { distanceBetweenOld = *addressUpdate.NewSitDistanceBetween } else { - distanceBetweenOld, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.OriginalAddress.PostalCode) + distanceBetweenOld, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.OriginalAddress.PostalCode, false) } if err != nil { return nil, err } // calculating distance between the new address update & the SIT - distanceBetweenNew, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode) + distanceBetweenNew, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode, false) if err != nil { return nil, err } @@ -607,7 +607,12 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc // this only applies to international shipments if shipment.PrimeEstimatedWeight != nil && shipment.MarketCode == models.MarketCodeInternational { - err := models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment) + // the db proc consumes the mileage needed, so we need to get that first + mileage, err := f.planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, true) + if err != nil { + return err + } + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, mileage) if err != nil { return err } diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index 863e1851d21..7f48aa03533 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -70,11 +70,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", + false, ).Return(2500, nil).Twice() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), nil, nil) @@ -125,6 +127,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("90210"), mock.AnythingOfType("94535"), + false, ).Return(0, fmt.Errorf("error calculating distance 2")).Once() testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ @@ -242,11 +245,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", + false, ).Return(2500, nil).Times(4) mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", + false, ).Return(2500, nil).Twice() update, err := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) @@ -272,11 +277,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), "89523", "89503", + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", + false, ).Return(2500, nil).Once() newAddress := models.Address{ StreetAddress1: "123 Any St", @@ -317,11 +324,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), "89523", "89503", + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -362,11 +371,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", + false, ).Return(0, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "89503", + false, ).Return(200, nil).Once() testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ @@ -489,11 +500,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), "87108", + false, ).Return(500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), "87053", + false, ).Return(501, nil).Once() suite.NotEmpty(move.MTOShipments) update, err := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) @@ -547,16 +560,19 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", + false, ).Return(0, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94523", "90210", + false, ).Return(500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "90210", + false, ).Return(501, nil).Once() // request the update @@ -582,6 +598,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) addressUpdateRequester := NewShipmentAddressUpdateRequester(mockPlanner, addressCreator, moveRouter) @@ -842,11 +859,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.AnythingOfType("*appcontext.appContext"), "89523", "89503", + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -908,11 +927,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.AnythingOfType("*appcontext.appContext"), "89523", "89503", + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -982,10 +1003,17 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp State: "CA", PostalCode: shipment.DestinationAddress.PostalCode, } + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "90210", + "94535", + false, + ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", + false, ).Return(2500, nil).Once() addressChange, _ := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) @@ -1007,11 +1035,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.AnythingOfType("*appcontext.appContext"), "89523", "89503", + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -1068,11 +1098,13 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.AnythingOfType("*appcontext.appContext"), "89523", "89503", + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", + false, ).Return(2500, nil).Once() newAddress := models.Address{ StreetAddress1: "123 Any St", diff --git a/pkg/services/sit_extension/sit_extension_denier.go b/pkg/services/sit_extension/sit_extension_denier.go index 4acb6cbc197..07cd9477c16 100644 --- a/pkg/services/sit_extension/sit_extension_denier.go +++ b/pkg/services/sit_extension/sit_extension_denier.go @@ -33,6 +33,7 @@ func NewSITExtensionDenier(moveRouter services.MoveRouter) services.SITExtension mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) return &sitExtensionDenier{moveRouter, mtoserviceitem.NewMTOServiceItemUpdater(planner, query.NewQueryBuilder(), moveRouter, mtoshipment.NewMTOShipmentFetcher(), address.NewAddressCreator(), portlocation.NewPortLocationFetcher())} } diff --git a/pkg/testdatagen/scenario/shared.go b/pkg/testdatagen/scenario/shared.go index 8d04108fd6b..dfe99dbda5b 100644 --- a/pkg/testdatagen/scenario/shared.go +++ b/pkg/testdatagen/scenario/shared.go @@ -4211,6 +4211,7 @@ func createHHGWithOriginSITServiceItems( mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) queryBuilder := query.NewQueryBuilder() @@ -4238,7 +4239,7 @@ func createHHGWithOriginSITServiceItems( // called for zip 3 domestic linehaul service item planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813").Return(2361, nil) + "90210", "30813", false).Return(2361, nil) shipmentUpdater := mtoshipment.NewMTOShipmentStatusUpdater(queryBuilder, serviceItemCreator, planner) _, updateErr := shipmentUpdater.UpdateMTOShipmentStatus(appCtx, shipment.ID, models.MTOShipmentStatusApproved, nil, nil, etag.GenerateEtag(shipment.UpdatedAt)) @@ -4289,6 +4290,7 @@ func createHHGWithOriginSITServiceItems( mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) serviceItemUpdator := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -4480,6 +4482,7 @@ func createHHGWithDestinationSITServiceItems(appCtx appcontext.AppContext, prime mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -4507,7 +4510,7 @@ func createHHGWithDestinationSITServiceItems(appCtx appcontext.AppContext, prime // called for zip 3 domestic linehaul service item planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813").Return(2361, nil) + "90210", "30813", false).Return(2361, nil) shipmentUpdater := mtoshipment.NewMTOShipmentStatusUpdater(queryBuilder, serviceItemCreator, planner) _, updateErr := shipmentUpdater.UpdateMTOShipmentStatus(appCtx, shipment.ID, models.MTOShipmentStatusApproved, nil, nil, etag.GenerateEtag(shipment.UpdatedAt)) @@ -4553,6 +4556,7 @@ func createHHGWithDestinationSITServiceItems(appCtx appcontext.AppContext, prime mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) serviceItemUpdator := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -4889,7 +4893,7 @@ func createHHGWithPaymentServiceItems( queryBuilder := query.NewQueryBuilder() planner := &routemocks.Planner{} - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything).Return(123, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(123, nil).Once() serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -4914,33 +4918,33 @@ func createHHGWithPaymentServiceItems( logger.Fatal("Error approving move") } // called using the addresses with origin zip of 90210 and destination zip of 94535 - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything).Return(348, nil).Times(2) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(348, nil).Times(2) // called using the addresses with origin zip of 90210 and destination zip of 90211 - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything).Return(3, nil).Times(5) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(3, nil).Times(5) // called for zip 3 domestic linehaul service item planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "94535", "94535").Return(348, nil).Times(2) + "94535", "94535", false).Return(348, nil).Times(2) // called for zip 5 domestic linehaul service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535").Return(348, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false).Return(348, nil).Once() // called for domestic shorthaul service item planner.On("Zip5TransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "90211").Return(3, nil).Times(7) // called for domestic shorthaul service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "90211").Return(348, nil).Times(10) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "90211", false).Return(348, nil).Times(10) // called for domestic origin SIT pickup service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "94535").Return(348, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", false).Return(348, nil).Once() // called for domestic destination SIT delivery service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "90210").Return(348, nil).Times(2) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "90210", false).Return(348, nil).Times(2) // called for DLH, DSH, FSC service item estimated price calculations - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything).Return(400, nil).Times(3) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(400, nil).Times(3) for _, shipment := range []models.MTOShipment{longhaulShipment, shorthaulShipment, shipmentWithOriginalWeight, shipmentWithOriginalAndReweighWeight, shipmentWithOriginalAndReweighWeightReweihBolded, shipmentWithOriginalReweighAndAdjustedWeight, shipmentWithOriginalAndAdjustedWeight} { shipmentUpdater := mtoshipment.NewMTOShipmentStatusUpdater(queryBuilder, serviceItemCreator, planner) @@ -5035,6 +5039,7 @@ func createHHGWithPaymentServiceItems( mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(400, nil) serviceItemUpdater := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -5522,6 +5527,7 @@ func createHHGMoveWithPaymentRequest(appCtx appcontext.AppContext, userUploader mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, + false, ).Return(910, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( diff --git a/pkg/testdatagen/testharness/make_move.go b/pkg/testdatagen/testharness/make_move.go index fd337bb029f..4cc88a4dc24 100644 --- a/pkg/testdatagen/testharness/make_move.go +++ b/pkg/testdatagen/testharness/make_move.go @@ -3823,7 +3823,7 @@ func MakeHHGMoveWithApprovedNTSShipmentsForTOO(appCtx appcontext.AppContext) mod planner := &routemocks.Planner{} // mock any and all planner calls - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything).Return(2361, nil) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(2361, nil) queryBuilder := query.NewQueryBuilder() serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -3927,7 +3927,7 @@ func MakeHHGMoveWithApprovedNTSRShipmentsForTOO(appCtx appcontext.AppContext) mo planner := &routemocks.Planner{} // mock any and all planner calls - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything).Return(2361, nil) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(2361, nil) queryBuilder := query.NewQueryBuilder() serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) From bedfd5ce9d4e9fa1c50cf778160ee5b254577535 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Tue, 17 Dec 2024 21:45:48 +0000 Subject: [PATCH 11/52] updating residual tests --- .../mto_shipment/shipment_approver.go | 22 +++++++++---------- .../shipment_address_update_requester_test.go | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index 01d92bcb179..a331b886822 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -78,17 +78,7 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen } transactionError := appCtx.NewTransaction(func(txnAppCtx appcontext.AppContext) error { - 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") - - return invalidInputError - } - if err != nil { - return err - } - - // create international shipment service items + // create international shipment service items before approving // we use a database proc to create the basic auto-approved service items if shipment.ShipmentType == models.MTOShipmentTypeHHG && shipment.MarketCode == models.MarketCodeInternational { err := models.CreateApprovedServiceItemsForShipment(appCtx.DB(), shipment) @@ -116,6 +106,16 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen } } + 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") + + return invalidInputError + } + if err != nil { + return err + } + return nil }) diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index 7f48aa03533..e38caadf2df 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -1159,7 +1159,8 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", - ).Return(30, nil).Once() + false, + ).Return(30, nil) move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), nil, nil) From 557617942cabd611c31bcfcf6e41ae2fdef93f60 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Wed, 18 Dec 2024 18:06:50 +0000 Subject: [PATCH 12/52] fixing broken tests after db-truncate changes, dear god save me --- pkg/handlers/primeapi/payment_request_test.go | 6 +- pkg/models/re_zip3s_test.go | 6 -- .../eia_fuel_price_lookup.go | 2 +- .../eia_fuel_price_lookup_test.go | 47 +------- pkg/route/dtod_planner_test.go | 11 -- pkg/route/hhg_planner_test.go | 32 +----- pkg/route/rand_mcnally_distance_test.go | 11 +- .../ghc_diesel_fuel_price_storer_test.go | 4 +- .../mto_shipment/shipment_approver.go | 2 +- .../mto_shipment/shipment_approver_test.go | 100 ++++++++++++++---- pkg/testdatagen/make_pricing_data.go | 6 +- scripts/db-truncate | 7 +- 12 files changed, 102 insertions(+), 132 deletions(-) diff --git a/pkg/handlers/primeapi/payment_request_test.go b/pkg/handlers/primeapi/payment_request_test.go index 1195c3f7750..5926d8ffbf8 100644 --- a/pkg/handlers/primeapi/payment_request_test.go +++ b/pkg/handlers/primeapi/payment_request_test.go @@ -28,7 +28,7 @@ import ( ) const ( - dlhTestServiceArea = "004" + dlhTestServiceArea = "042" dlhTestWeight = unit.Pound(4000) ) @@ -648,7 +648,7 @@ func (suite *HandlerSuite) setupDomesticLinehaulData() (models.Move, models.MTOS }, }) - baseLinehaulPrice := testdatagen.MakeReDomesticLinehaulPrice(suite.DB(), testdatagen.Assertions{ + baseLinehaulPrice := testdatagen.FetchOrMakeReDomesticLinehaulPrice(suite.DB(), testdatagen.Assertions{ ReDomesticLinehaulPrice: models.ReDomesticLinehaulPrice{ ContractID: contractYear.Contract.ID, Contract: contractYear.Contract, @@ -658,7 +658,7 @@ func (suite *HandlerSuite) setupDomesticLinehaulData() (models.Move, models.MTOS }, }) - _ = testdatagen.MakeReDomesticLinehaulPrice(suite.DB(), testdatagen.Assertions{ + _ = testdatagen.FetchOrMakeReDomesticLinehaulPrice(suite.DB(), testdatagen.Assertions{ ReDomesticLinehaulPrice: models.ReDomesticLinehaulPrice{ ContractID: contractYear.Contract.ID, Contract: contractYear.Contract, diff --git a/pkg/models/re_zip3s_test.go b/pkg/models/re_zip3s_test.go index 3395842216d..79a5d70c613 100644 --- a/pkg/models/re_zip3s_test.go +++ b/pkg/models/re_zip3s_test.go @@ -4,7 +4,6 @@ import ( "github.com/gofrs/uuid" "github.com/transcom/mymove/pkg/models" - "github.com/transcom/mymove/pkg/testdatagen" ) func (suite *ModelSuite) TestReZip3Validations() { @@ -48,11 +47,6 @@ func (suite *ModelSuite) TestReZip3Validations() { suite.Run("test FetchReZip3Item", func() { zip3 := "606" - testdatagen.MakeReZip3(suite.DB(), testdatagen.Assertions{ - ReZip3: models.ReZip3{ - Zip3: zip3, - }, - }) reZip3, err := models.FetchReZip3Item(suite.DB(), zip3) suite.Nil(err) diff --git a/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup.go b/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup.go index 9e5e29cc188..9d60fd9e7b1 100644 --- a/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup.go @@ -22,7 +22,7 @@ func (r EIAFuelPriceLookup) lookup(appCtx appcontext.AppContext, _ *ServiceItemP // Make sure there is an actual pickup date since ActualPickupDate is nullable actualPickupDate := r.MTOShipment.ActualPickupDate if actualPickupDate == nil { - return "", fmt.Errorf("not found looking for pickup address") + return "", fmt.Errorf("not found looking for shipment pickup date") } // Find the GHCDieselFuelPrice object effective before the shipment's ActualPickupDate and ends after the ActualPickupDate diff --git a/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup_test.go b/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup_test.go index ded105300ab..2b310cbcdc0 100644 --- a/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/eia_fuel_price_lookup_test.go @@ -207,53 +207,16 @@ func (suite *ServiceParamValueLookupsSuite) TestEIAFuelPriceLookupWithInvalidAct suite.Run("lookup GHC diesel fuel price with nil actual pickup date", func() { setupTestData() - - paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) + var shipment models.MTOShipment + err := suite.DB().Find(&shipment, mtoServiceItem.MTOShipmentID) suite.FatalNoError(err) - _, err = paramLookup.ServiceParamValue(suite.AppContextForTest(), key) - suite.Error(err) - suite.Contains(err.Error(), "EIAFuelPriceLookup with error Not found Looking for GHCDieselFuelPrice") - }) -} - -func (suite *ServiceParamValueLookupsSuite) TestEIAFuelPriceLookupWithNoGHCDieselFuelPriceData() { - key := models.ServiceItemParamNameEIAFuelPrice - var mtoServiceItem models.MTOServiceItem - var paymentRequest models.PaymentRequest - actualPickupDate := time.Date(2020, time.July, 15, 0, 0, 0, 0, time.UTC) - - setupTestData := func() { - testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ - ReContractYear: models.ReContractYear{ - StartDate: time.Now().Add(-24 * time.Hour), - EndDate: time.Now().Add(24 * time.Hour), - }, - }) - mtoServiceItem = factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ - { - Model: models.MTOShipment{ - ActualPickupDate: &actualPickupDate, - }, - }, - }, []factory.Trait{ - factory.GetTraitAvailableToPrimeMove, - }) - - paymentRequest = factory.BuildPaymentRequest(suite.DB(), []factory.Customization{ - { - Model: mtoServiceItem.MoveTaskOrder, - LinkOnly: true, - }, - }, nil) - } - - suite.Run("lookup GHC diesel fuel price with no data", func() { - setupTestData() + shipment.ActualPickupDate = nil + suite.MustSave(&shipment) paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) suite.FatalNoError(err) _, err = paramLookup.ServiceParamValue(suite.AppContextForTest(), key) suite.Error(err) - suite.Contains(err.Error(), "Looking for GHCDieselFuelPrice") + suite.Contains(err.Error(), "EIAFuelPriceLookup with error not found looking for shipment pickup date") }) } diff --git a/pkg/route/dtod_planner_test.go b/pkg/route/dtod_planner_test.go index 9f419401e7e..02e811e31d4 100644 --- a/pkg/route/dtod_planner_test.go +++ b/pkg/route/dtod_planner_test.go @@ -18,7 +18,6 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/route/ghcmocks" - "github.com/transcom/mymove/pkg/testdatagen" "github.com/transcom/mymove/pkg/testingsuite" ) @@ -99,16 +98,6 @@ func (suite *GHCTestSuite) TestDTODZipTransitDistance() { mock.Anything, ).Return(soapResponseForDistance("150.33"), nil) - sourceZip3 := "303" - destinationZip3 := "309" - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: sourceZip3, - ToZip3: destinationZip3, - DistanceMiles: 150, - }, - }) - plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewDTODPlanner(plannerMileage) distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false) diff --git a/pkg/route/hhg_planner_test.go b/pkg/route/hhg_planner_test.go index ba16a28d019..a2725ef1c3a 100644 --- a/pkg/route/hhg_planner_test.go +++ b/pkg/route/hhg_planner_test.go @@ -15,7 +15,6 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/route/ghcmocks" - "github.com/transcom/mymove/pkg/testdatagen" ) func (suite *GHCTestSuite) TestHHGTransitDistance() { @@ -77,21 +76,11 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { mock.Anything, ).Return(soapResponseForDistance("150.33"), nil) - sourceZip3 := "303" - destinationZip3 := "309" - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: sourceZip3, - ToZip3: destinationZip3, - DistanceMiles: 150, - }, - }) - plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false) suite.NoError(err) - suite.Equal(150, distance) + suite.Equal(149, distance) }) suite.Run("ZipTransitDistance returns a distance of 1 if origin and dest zips are the same", func() { @@ -112,25 +101,6 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { mock.Anything, ).Return(soapResponseForDistance("166"), nil) - // Create two zip3s in the same base point city (Miami) - testdatagen.MakeReZip3(suite.DB(), testdatagen.Assertions{ - ReZip3: models.ReZip3{ - Zip3: "330", - BasePointCity: "Miami", - State: "FL", - }, - }) - testdatagen.MakeReZip3(suite.DB(), testdatagen.Assertions{ - ReZip3: models.ReZip3{ - Zip3: "331", - BasePointCity: "Miami", - State: "FL", - }, - ReDomesticServiceArea: models.ReDomesticServiceArea{ - ServiceArea: "005", - }, - }) - plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) diff --git a/pkg/route/rand_mcnally_distance_test.go b/pkg/route/rand_mcnally_distance_test.go index 1710194636c..d8b227a5080 100644 --- a/pkg/route/rand_mcnally_distance_test.go +++ b/pkg/route/rand_mcnally_distance_test.go @@ -1,27 +1,20 @@ package route -import ( - "github.com/transcom/mymove/pkg/testdatagen" -) - func (suite *GHCTestSuite) TestRandMcNallyZip3Distance() { suite.Run("test basic distance check", func() { - testdatagen.MakeDefaultZip3Distance(suite.DB()) distance, err := randMcNallyZip3Distance(suite.AppContextForTest(), "010", "011") suite.NoError(err) - suite.Equal(24, distance) + suite.Equal(12, distance) }) suite.Run("fromZip3 is greater than toZip3", func() { - testdatagen.MakeDefaultZip3Distance(suite.DB()) distance, err := randMcNallyZip3Distance(suite.AppContextForTest(), "011", "010") suite.NoError(err) - suite.Equal(24, distance) + suite.Equal(12, distance) }) suite.Run("fromZip3 is the same as toZip3", func() { - testdatagen.MakeDefaultZip3Distance(suite.DB()) distance, err := randMcNallyZip3Distance(suite.AppContextForTest(), "010", "010") suite.Equal(0, distance) suite.NotNil(err) diff --git a/pkg/services/ghcdieselfuelprice/ghc_diesel_fuel_price_storer_test.go b/pkg/services/ghcdieselfuelprice/ghc_diesel_fuel_price_storer_test.go index 95188677e61..bbd563fc017 100644 --- a/pkg/services/ghcdieselfuelprice/ghc_diesel_fuel_price_storer_test.go +++ b/pkg/services/ghcdieselfuelprice/ghc_diesel_fuel_price_storer_test.go @@ -32,8 +32,8 @@ func (suite *GHCDieselFuelPriceServiceSuite) Test_ghcDieselFuelPriceStorer() { var ghcDieselFuelPrice models.GHCDieselFuelPrice err = suite.DB().Last(&ghcDieselFuelPrice) suite.NoError(err) - suite.Equal("2020-06-22T00:00:00Z", ghcDieselFuelPrice.PublicationDate.Format(time.RFC3339)) - suite.Equal(unit.Millicents(265900), ghcDieselFuelPrice.FuelPriceInMillicents) + suite.Equal("2020-04-06T00:00:00Z", ghcDieselFuelPrice.PublicationDate.Format(time.RFC3339)) + suite.Equal(unit.Millicents(254800), ghcDieselFuelPrice.FuelPriceInMillicents) }) diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index a331b886822..eadc0229aa1 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -99,7 +99,7 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen } } } else { - // after approving shipment, shipment level service items must be created + // after approving shipment, shipment level service items must be created (this is for domestic shipments only) err = f.createShipmentServiceItems(txnAppCtx, shipment) if err != nil { return err diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 5902d863901..109d0822eec 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -14,7 +14,6 @@ import ( "github.com/transcom/mymove/pkg/etag" "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" - "github.com/transcom/mymove/pkg/route" "github.com/transcom/mymove/pkg/route/mocks" "github.com/transcom/mymove/pkg/services" "github.com/transcom/mymove/pkg/services/ghcrateengine" @@ -191,50 +190,105 @@ 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() { - internationalShipment := factory.BuildMTOShipment(suite.AppContextForTest().DB(), []factory.Customization{ + suite.Run("If the international mtoShipment is approved successfully it should create pre approved mtoServiceItems and update pricing when there is estimated weight", func() { + move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ { Model: models.Move{ Status: models.MoveStatusAPPROVED, }, + }}, nil) + + // we need to get the usPostRegionCityIDs based off of the ZIP for the addresses + pickupUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "50314") + suite.FatalNoError(err) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &pickupUSPRC.ID, + }, }, + }, nil) + + destUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + suite.FatalNoError(err) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ { Model: models.Address{ - StreetAddress1: "Tester Address", - City: "Des Moines", - State: "IA", - PostalCode: "50314", - IsOconus: models.BoolPointer(false), + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, }, - Type: &factory.Addresses.PickupAddress, }, + }, nil) + + pickupDate := time.Now() + internationalShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ { Model: models.MTOShipment{ - MarketCode: "i", - Status: models.MTOShipmentStatusSubmitted, + Status: models.MTOShipmentStatusSubmitted, + MarketCode: models.MarketCodeInternational, + PrimeEstimatedWeight: models.PoundPointer(unit.Pound(4000)), + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + RequestedPickupDate: &pickupDate, }, }, { - Model: models.Address{ - StreetAddress1: "JBER", - City: "Anchorage", - State: "AK", - PostalCode: "99505", - IsOconus: models.BoolPointer(true), - }, - Type: &factory.Addresses.DeliveryAddress, + Model: move, + LinkOnly: true, }, }, nil) internationalShipmentEtag := etag.GenerateEtag(internationalShipment.UpdatedAt) + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + shipmentRouter := NewShipmentRouter() + moveWeights := moverouter.NewMoveWeights(NewShipmentReweighRequester()) var serviceItemCreator services.MTOServiceItemCreator - var planner route.Planner - var moveWeights services.MoveWeights + appCtx := suite.AppContextWithSessionForTest(&auth.Session{ + ApplicationName: auth.OfficeApp, + OfficeUserID: uuid.Must(uuid.NewV4()), + }) + + ghcDomesticTransitTime := models.GHCDomesticTransitTime{ + MaxDaysTransitTime: 12, + WeightLbsLower: 0, + WeightLbsUpper: 10000, + DistanceMilesLower: 0, + DistanceMilesUpper: 10000, + } + _, _ = suite.DB().ValidateAndCreate(&ghcDomesticTransitTime) + + planner := &mocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + ).Return(500, nil) + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "50314", + "99505", + true, + ).Return(1000, nil) // Approve international shipment shipmentApprover := NewShipmentApprover(shipmentRouter, serviceItemCreator, planner, moveWeights) - _, err := shipmentApprover.ApproveShipment(suite.AppContextForTest(), internationalShipment.ID, internationalShipmentEtag) + _, err = shipmentApprover.ApproveShipment(appCtx, internationalShipment.ID, internationalShipmentEtag) suite.NoError(err) // Get created pre approved service items @@ -253,6 +307,8 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { for i := 0; i < len(serviceItems); i++ { actualReServiceCode := serviceItems[i].ReService.Code suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) + // because the estimated weight is provided, estimated pricing should be updated + suite.NotNil(serviceItems[i].PricingEstimate) } }) diff --git a/pkg/testdatagen/make_pricing_data.go b/pkg/testdatagen/make_pricing_data.go index 02a855a8c93..61ebfb7231d 100644 --- a/pkg/testdatagen/make_pricing_data.go +++ b/pkg/testdatagen/make_pricing_data.go @@ -20,7 +20,7 @@ func SetupServiceAreaRateArea(db *pop.Connection, assertions Assertions) (models mergeModels(&contractYear, assertions.ReContractYear) - contractYear = MakeReContractYear(db, Assertions{ReContractYear: contractYear}) + contractYear = FetchOrMakeReContractYear(db, Assertions{ReContractYear: contractYear}) serviceArea := models.ReDomesticServiceArea{ Contract: contractYear.Contract, @@ -29,7 +29,7 @@ func SetupServiceAreaRateArea(db *pop.Connection, assertions Assertions) (models mergeModels(&serviceArea, assertions.ReDomesticServiceArea) - serviceArea = MakeReDomesticServiceArea(db, + serviceArea = FetchOrMakeReDomesticServiceArea(db, Assertions{ ReDomesticServiceArea: serviceArea, }) @@ -64,7 +64,7 @@ func SetupServiceAreaRateArea(db *pop.Connection, assertions Assertions) (models mergeModels(&reZip3, assertions.ReZip3) - reZip3 = MakeReZip3(db, Assertions{ + reZip3 = FetchOrMakeReZip3(db, Assertions{ ReZip3: reZip3, }) diff --git a/scripts/db-truncate b/scripts/db-truncate index a0f15bc3450..33ad3af6370 100755 --- a/scripts/db-truncate +++ b/scripts/db-truncate @@ -9,7 +9,12 @@ DO \$\$ DECLARE r RECORD; BEGIN FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema() - AND tablename NOT IN ('us_post_region_cities', 're_countries', 're_states', 're_cities', 're_us_post_regions', 're_oconus_rate_areas', 're_rate_areas', 're_intl_transit_times', 'ub_allowances','re_services','re_service_items', 'ports', 'port_locations', 're_fsc_multipliers')) LOOP + AND tablename NOT IN ('us_post_region_cities', 're_countries', 're_states', 're_cities', + 're_us_post_regions', 're_oconus_rate_areas', 're_rate_areas', + 're_intl_transit_times', 'ub_allowances','re_services','re_service_items', + 'ports', 'port_locations', 're_fsc_multipliers', 'ghc_diesel_fuel_prices', + 're_zip3s', 'zip3_distances', 're_contracts', 're_domestic_service_areas', + 're_intl_prices', 're_intl_other_prices', 're_domestic_linehaul_prices')) LOOP EXECUTE 'TRUNCATE TABLE ' || quote_ident(r.tablename) || ' CASCADE'; END LOOP; END \$\$; From bb6ed3ca4db015f4a016de4679d3fe3cc1710a4c Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Wed, 18 Dec 2024 19:06:08 +0000 Subject: [PATCH 13/52] shipment updater test added --- .../mto_shipment/mto_shipment_updater.go | 8 +- .../mto_shipment/mto_shipment_updater_test.go | 200 +++++++++++++++++- 2 files changed, 200 insertions(+), 8 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 61d61e386ee..8670720cbd2 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -855,10 +855,10 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, // we will compare data here to see if we even need to update the pricing if newShipment.PrimeEstimatedWeight != nil && newShipment.MarketCode == models.MarketCodeInternational && - (*newShipment.PrimeEstimatedWeight != *dbShipment.PrimeEstimatedWeight || - newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || - newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || - newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { + (newShipment.PrimeEstimatedWeight != dbShipment.PrimeEstimatedWeight || + newShipment.PickupAddress != nil && newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || + newShipment.DestinationAddress != nil && newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || + newShipment.RequestedPickupDate != nil && newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { // the db proc consumes the mileage needed, so we need to get that first mileage, err := f.planner.ZipTransitDistance(appCtx, newShipment.PickupAddress.PostalCode, newShipment.DestinationAddress.PostalCode, true) diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index fab08803ece..cc11aa6678c 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -458,6 +458,202 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { suite.Equal(updatedShipment.MarketCode, models.MarketCodeInternational) }) + suite.Run("Successful update on international shipment with estimated weight results in the of basic pricing service items", func() { + setupTestData() + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "50314", + "99505", + true, + ).Return(1000, nil) + + ghcDomesticTransitTime := models.GHCDomesticTransitTime{ + MaxDaysTransitTime: 12, + WeightLbsLower: 0, + WeightLbsUpper: 10000, + DistanceMilesLower: 0, + DistanceMilesUpper: 10000, + } + _, _ = suite.DB().ValidateAndCreate(&ghcDomesticTransitTime) + + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + + pickupUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "50314") + suite.FatalNoError(err) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &pickupUSPRC.ID, + }, + }, + }, nil) + + destUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + suite.FatalNoError(err) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, + }, + }, + }, nil) + + pickupDate := now.AddDate(0, 0, 10) + requestedPickup := time.Now() + oldShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + PrimeEstimatedWeight: nil, + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + ScheduledPickupDate: &pickupDate, + RequestedPickupDate: &requestedPickup, + }, + }, + { + Model: move, + LinkOnly: true, + }, + }, nil) + + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: oldShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeISLH, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: oldShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: oldShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHUPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: oldShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + { + Model: portLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfEmbarkation, + }, + }, nil) + + eTag := etag.GenerateEtag(oldShipment.UpdatedAt) + + updatedShipment := models.MTOShipment{ + ID: oldShipment.ID, + PrimeEstimatedWeight: &primeEstimatedWeight, + } + + session := auth.Session{} + _, err = mtoShipmentUpdaterPrime.UpdateMTOShipment(suite.AppContextWithSessionForTest(&session), &updatedShipment, eTag, "test") + suite.NoError(err) + + // checking the service item data + var serviceItems []models.MTOServiceItem + err = suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", oldShipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err) + + suite.Equal(4, len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + // because the estimated weight is provided, estimated pricing should be updated + suite.NotNil(serviceItems[i].PricingEstimate) + } + }) + suite.Run("Successful update to a minimal MTO shipment", func() { setupTestData() @@ -1128,10 +1324,6 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { suite.Run("Prime not able to update an existing prime estimated weight", func() { setupTestData() - // This test was added because of a bug that nullified the ApprovedDate - // when ScheduledPickupDate was included in the payload. See PR #6919. - // ApprovedDate affects shipment diversions, so we want to make sure it - // never gets nullified, regardless of which fields are being updated. move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) oldShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ { From 9a04366d1e0bf8af45d1586dd96f3cb24496bf40 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Wed, 18 Dec 2024 19:58:28 +0000 Subject: [PATCH 14/52] updating pricer tests since we arent dropping tables now --- ...import_re_domestic_linehaul_prices_test.go | 2 +- .../import_re_intl_other_prices_test.go | 2 +- .../ghcimport/import_re_intl_prices_test.go | 2 +- ...ic_destination_sit_delivery_pricer_test.go | 10 +++---- .../domestic_linehaul_pricer_test.go | 9 +++--- .../domestic_origin_sit_pickup_pricer_test.go | 4 +-- .../ghc_rate_engine_service_test.go | 29 ++++++------------- .../ghcrateengine/pricer_helpers_test.go | 2 +- .../make_re_domestic_service_area.go | 14 ++++++--- 9 files changed, 33 insertions(+), 41 deletions(-) diff --git a/pkg/services/ghcimport/import_re_domestic_linehaul_prices_test.go b/pkg/services/ghcimport/import_re_domestic_linehaul_prices_test.go index 7d79bf37b98..32b16b4fced 100644 --- a/pkg/services/ghcimport/import_re_domestic_linehaul_prices_test.go +++ b/pkg/services/ghcimport/import_re_domestic_linehaul_prices_test.go @@ -45,7 +45,7 @@ func (suite *GHCRateEngineImportSuite) Test_importREDomesticLinehaulPrices() { func (suite *GHCRateEngineImportSuite) helperVerifyDomesticLinehaulCount() { count, err := suite.DB().Count(&models.ReDomesticLinehaulPrice{}) suite.NoError(err) - suite.Equal(240, count) + suite.Equal(13800, count) } func (suite *GHCRateEngineImportSuite) helperCheckDomesticLinehaulValue() { diff --git a/pkg/services/ghcimport/import_re_intl_other_prices_test.go b/pkg/services/ghcimport/import_re_intl_other_prices_test.go index 8818f531cc8..8dc6fd4ce47 100644 --- a/pkg/services/ghcimport/import_re_intl_other_prices_test.go +++ b/pkg/services/ghcimport/import_re_intl_other_prices_test.go @@ -49,7 +49,7 @@ func (suite *GHCRateEngineImportSuite) Test_importREInternationalOtherPrices() { func (suite *GHCRateEngineImportSuite) helperVerifyInternationalOtherPrices() { count, err := suite.DB().Count(&models.ReIntlOtherPrice{}) suite.NoError(err) - suite.Equal(180, count) + suite.Equal(2580, count) } func (suite *GHCRateEngineImportSuite) helperCheckInternationalOtherPriceRecords() { diff --git a/pkg/services/ghcimport/import_re_intl_prices_test.go b/pkg/services/ghcimport/import_re_intl_prices_test.go index 13d9f74ffd8..976da15d0ab 100644 --- a/pkg/services/ghcimport/import_re_intl_prices_test.go +++ b/pkg/services/ghcimport/import_re_intl_prices_test.go @@ -102,7 +102,7 @@ func (suite *GHCRateEngineImportSuite) Test_getRateAreaIDForKind() { func (suite *GHCRateEngineImportSuite) helperVerifyInternationalPrices() { count, err := suite.DB().Count(&models.ReIntlPrice{}) suite.NoError(err) - suite.Equal(276, count) + suite.Equal(27466406, count) } func (suite *GHCRateEngineImportSuite) helperCheckInternationalPriceValues() { diff --git a/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go b/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go index a1b0950e605..177839fc54d 100644 --- a/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go @@ -23,7 +23,7 @@ const ( dddsitTestMilesLower = 251 dddsitTestMilesUpper = 500 dddsitTestDomesticOtherBasePriceCents = unit.Cents(2518) - dddsitTestDomesticLinehaulBasePriceMillicents = unit.Millicents(6500) + dddsitTestDomesticLinehaulBasePriceMillicents = unit.Millicents(237900) dddsitTestDomesticServiceAreaBasePriceCents = unit.Cents(153) ) @@ -104,7 +104,7 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer }) suite.Run("bad SIT final destination service area using ServiceAreaLookup", func() { - suite.setupDomesticServiceAreaPrice(models.ReServiceCodeDSH, "", dddsitTestIsPeakPeriod, dddsitTestDomesticServiceAreaBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) + suite.setupDomesticServiceAreaPrice(models.ReServiceCodeDSH, dddsitTestServiceArea, dddsitTestIsPeakPeriod, dddsitTestDomesticServiceAreaBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) _, _, err := pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, dddsitTestRequestedPickupDate, dddsitTestWeight, "111", dddsitTestSchedule, zipDest, zipSITDest, distance) suite.Error(err) @@ -112,7 +112,6 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer }) suite.Run("error from shorthaul pricer", func() { - //suite.setupDomesticServiceAreaPrice(models.ReServiceCodeDSH, dddsitTestServiceArea, dddsitTestIsPeakPeriod, dddsitTestDomesticServiceAreaBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) _, _, err := pricer.Price(suite.AppContextForTest(), "BOGUS", dddsitTestRequestedPickupDate, dddsitTestWeight, dddsitTestServiceArea, dddsitTestSchedule, zipDest, zipSITDest, distance) @@ -123,12 +122,11 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer50PlusMilesDiffZip3s() { zipDest := "30907" - zipSITDest := "36106" // different zip3 - //sitServiceAreaDest := "020" // different service Area + zipSITDest := "36106" // different zip3 distance := unit.Miles(305) // > 50 miles pricer := NewDomesticDestinationSITDeliveryPricer() - expectedPrice := unit.Cents(45979) + expectedPrice := unit.Cents(1681313) suite.Run("success using PaymentServiceItemParams", func() { suite.setupDomesticLinehaulPrice(dddsitTestServiceArea, dddsitTestIsPeakPeriod, dddsitTestWeightLower, dddsitTestWeightUpper, dddsitTestMilesLower, dddsitTestMilesUpper, dddsitTestDomesticLinehaulBasePriceMillicents, dddsitTestContractYearName, dddsitTestEscalationCompounded) diff --git a/pkg/services/ghcrateengine/domestic_linehaul_pricer_test.go b/pkg/services/ghcrateengine/domestic_linehaul_pricer_test.go index 8a5b187fc2c..5365abdbb3c 100644 --- a/pkg/services/ghcrateengine/domestic_linehaul_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_linehaul_pricer_test.go @@ -18,12 +18,12 @@ const ( dlhTestWeightUpper = unit.Pound(4999) dlhTestMilesLower = 1001 dlhTestMilesUpper = 1500 - dlhTestBasePriceMillicents = unit.Millicents(5111) + dlhTestBasePriceMillicents = unit.Millicents(388600) dlhTestContractYearName = "DLH Test Year" dlhTestEscalationCompounded = 1.04071 dlhTestDistance = unit.Miles(1201) dlhTestWeight = unit.Pound(4001) - dlhPriceCents = unit.Cents(254676) + dlhPriceCents = unit.Cents(19432233) ) var dlhRequestedPickupDate = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) @@ -32,7 +32,6 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticLinehaul() { linehaulServicePricer := NewDomesticLinehaulPricer() suite.Run("success using PaymentServiceItemParams", func() { - // serviceArea := "sa0" suite.setupDomesticLinehaulPrice(dlhTestServiceArea, dlhTestIsPeakPeriod, dlhTestWeightLower, dlhTestWeightUpper, dlhTestMilesLower, dlhTestMilesUpper, dlhTestBasePriceMillicents, dlhTestContractYearName, dlhTestEscalationCompounded) paymentServiceItem := suite.setupDomesticLinehaulServiceItem() priceCents, displayParams, err := linehaulServicePricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) @@ -87,7 +86,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticLinehaul() { // < 50 mile distance with PPM priceCents, _, err := linehaulServicePricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, dlhRequestedPickupDate, unit.Miles(49), dlhTestWeight, dlhTestServiceArea, isPPM) suite.NoError(err) - suite.Equal(unit.Cents(10391), priceCents) + suite.Equal(unit.Cents(526980), priceCents) }) suite.Run("successfully finds linehaul price for ppm with distance < 50 miles with PriceUsingParams method", func() { @@ -202,7 +201,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticLinehaul() { _, _, err = linehaulServicePricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, time.Date(testdatagen.TestYear+1, 1, 1, 1, 1, 1, 1, time.UTC), dlhTestDistance, dlhTestWeight, dlhTestServiceArea, isPPM) suite.Error(err) - suite.Contains(err.Error(), "could not fetch domestic linehaul rate") + suite.Contains(err.Error(), "could not lookup contract year") }) } diff --git a/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go b/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go index 3a443ee47f7..2fe3c99de4f 100644 --- a/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go @@ -23,7 +23,7 @@ const ( dopsitTestMilesLower = 51 dopsitTestMilesUpper = 250 dopsitTestDomesticOtherBasePriceCents = unit.Cents(2810) - dopsitTestDomesticLinehaulBasePriceMillicents = unit.Millicents(4455) + dopsitTestDomesticLinehaulBasePriceMillicents = unit.Millicents(200300) dopsitTestDomesticServiceAreaBasePriceCents = unit.Cents(223) ) @@ -113,7 +113,7 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticOriginSITPickupPricer50PlusM distance := unit.Miles(77) // > 50 miles pricer := NewDomesticOriginSITPickupPricer() - expectedPrice := unit.Cents(16485) + expectedPrice := unit.Cents(733738) suite.Run("success using PaymentServiceItemParams", func() { suite.setupDomesticLinehaulPrice(dopsitTestServiceArea, dopsitTestIsPeakPeriod, dopsitTestWeightLower, dopsitTestWeightUpper, dopsitTestMilesLower, dopsitTestMilesUpper, dopsitTestDomesticLinehaulBasePriceMillicents, dopsitTestContractYearName, dopsitTestEscalationCompounded) diff --git a/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go b/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go index 0ed120492f8..df07775c20b 100644 --- a/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go +++ b/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go @@ -38,7 +38,7 @@ func (suite *GHCRateEngineServiceSuite) setupTaskOrderFeeData(code models.ReServ } func (suite *GHCRateEngineServiceSuite) setupDomesticOtherPrice(code models.ReServiceCode, schedule int, isPeakPeriod bool, priceCents unit.Cents, contractYearName string, escalationCompounded float64) { - contractYear := testdatagen.MakeReContractYear(suite.DB(), + contractYear := testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ Name: contractYearName, @@ -60,7 +60,7 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticOtherPrice(code models.ReSe } func (suite *GHCRateEngineServiceSuite) setupDomesticAccessorialPrice(code models.ReServiceCode, schedule int, perUnitCents unit.Cents, contractYearName string, escalationCompounded float64) { - contractYear := testdatagen.MakeReContractYear(suite.DB(), + contractYear := testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ Name: contractYearName, @@ -81,7 +81,7 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticAccessorialPrice(code model } func (suite *GHCRateEngineServiceSuite) setupDomesticServiceAreaPrice(code models.ReServiceCode, serviceAreaCode string, isPeakPeriod bool, priceCents unit.Cents, contractYearName string, escalationCompounded float64) { - contractYear := testdatagen.MakeReContractYear(suite.DB(), + contractYear := testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ Name: contractYearName, @@ -91,9 +91,10 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticServiceAreaPrice(code model service := factory.FetchReServiceByCode(suite.DB(), code) - serviceArea := testdatagen.MakeReDomesticServiceArea(suite.DB(), + serviceArea := testdatagen.FetchOrMakeReDomesticServiceArea(suite.DB(), testdatagen.Assertions{ ReDomesticServiceArea: models.ReDomesticServiceArea{ + ContractID: contractYear.Contract.ID, Contract: contractYear.Contract, ServiceArea: serviceAreaCode, }, @@ -111,7 +112,7 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticServiceAreaPrice(code model } func (suite *GHCRateEngineServiceSuite) setupDomesticLinehaulPrice(serviceAreaCode string, isPeakPeriod bool, weightLower unit.Pound, weightUpper unit.Pound, milesLower int, milesUpper int, priceMillicents unit.Millicents, contractYearName string, escalationCompounded float64) { - contractYear := testdatagen.MakeReContractYear(suite.DB(), + contractYear := testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ Name: contractYearName, @@ -119,30 +120,18 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticLinehaulPrice(serviceAreaCo }, }) - serviceArea := testdatagen.MakeReDomesticServiceArea(suite.DB(), + testdatagen.FetchOrMakeReDomesticServiceArea(suite.DB(), testdatagen.Assertions{ ReDomesticServiceArea: models.ReDomesticServiceArea{ + ContractID: contractYear.Contract.ID, Contract: contractYear.Contract, ServiceArea: serviceAreaCode, }, }) - - baseLinehaulPrice := models.ReDomesticLinehaulPrice{ - ContractID: contractYear.Contract.ID, - WeightLower: weightLower, - WeightUpper: weightUpper, - MilesLower: milesLower, - MilesUpper: milesUpper, - IsPeakPeriod: isPeakPeriod, - DomesticServiceAreaID: serviceArea.ID, - PriceMillicents: priceMillicents, - } - - suite.MustSave(&baseLinehaulPrice) } func (suite *GHCRateEngineServiceSuite) setupShipmentTypePrice(code models.ReServiceCode, market models.Market, factor float64, contractYearName string, escalationCompounded float64) { - contractYear := testdatagen.MakeReContractYear(suite.DB(), + contractYear := testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ Name: contractYearName, diff --git a/pkg/services/ghcrateengine/pricer_helpers_test.go b/pkg/services/ghcrateengine/pricer_helpers_test.go index 9adfa70f58e..7e5921c68b2 100644 --- a/pkg/services/ghcrateengine/pricer_helpers_test.go +++ b/pkg/services/ghcrateengine/pricer_helpers_test.go @@ -308,7 +308,7 @@ func (suite *GHCRateEngineServiceSuite) Test_priceDomesticPickupDeliverySIT50Plu suite.setupDomesticLinehaulPrice(dddsitTestServiceArea, dddsitTestIsPeakPeriod, dddsitTestWeightLower, dddsitTestWeightUpper, dddsitTestMilesLower, dddsitTestMilesUpper, dddsitTestDomesticLinehaulBasePriceMillicents, dlhContractName, dddsitTestEscalationCompounded) priceCents, displayParams, err := priceDomesticPickupDeliverySIT(suite.AppContextForTest(), models.ReServiceCodeDDDSIT, testdatagen.DefaultContractCode, dddsitTestRequestedPickupDate, dddsitTestWeight, dddsitTestServiceArea, dddsitTestSchedule, dlhZipDest, dlhZipSITDest, dlhDistance) suite.NoError(err) - expectedPrice := unit.Cents(45979) + expectedPrice := unit.Cents(1681313) suite.Equal(expectedPrice, priceCents) diff --git a/pkg/testdatagen/make_re_domestic_service_area.go b/pkg/testdatagen/make_re_domestic_service_area.go index 411dee468ca..5f57b4cd3dc 100644 --- a/pkg/testdatagen/make_re_domestic_service_area.go +++ b/pkg/testdatagen/make_re_domestic_service_area.go @@ -54,10 +54,16 @@ func FetchOrMakeReDomesticServiceArea(db *pop.Connection, assertions Assertions) } var reDomesticServiceArea models.ReDomesticServiceArea - err := db.Where("re_domestic_service_areas.contract_id = ? AND re_domestic_service_areas.service_area = ?", contractID, assertions.ReDomesticServiceArea.ServiceArea).First(&reDomesticServiceArea) - - if err != nil && err != sql.ErrNoRows { - log.Panic(err) + if assertions.ReDomesticServiceArea.ServiceArea != "" { + err := db.Where("re_domestic_service_areas.service_area = ?", assertions.ReDomesticServiceArea.ServiceArea).First(&reDomesticServiceArea) + if err != nil && err != sql.ErrNoRows { + log.Panic(err) + } + } else { + err := db.Where("re_domestic_service_areas.contract_id = ? AND re_domestic_service_areas.service_area = ?", contractID, assertions.ReDomesticServiceArea.ServiceArea).First(&reDomesticServiceArea) + if err != nil && err != sql.ErrNoRows { + log.Panic(err) + } } if reDomesticServiceArea.ID == uuid.Nil { From 489de3646843aad1b0d3e53f70d501f7d0b87cc0 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Wed, 18 Dec 2024 22:51:08 +0000 Subject: [PATCH 15/52] fixing headache failing tests after db truncate changes --- pkg/factory/domestic_other_prices.go | 49 ++++++ pkg/factory/domestic_other_prices_test.go | 30 ++++ pkg/factory/shared.go | 2 + .../payment_request_creator_test.go | 2 +- .../payment_request_recalculator_test.go | 23 +-- .../postal_code_validator_test.go | 140 +----------------- .../ppm_closeout/ppm_closeout_test.go | 71 ++++----- .../ppmshipment/ppm_estimator_test.go | 30 ++-- .../shipment_address_update_requester_test.go | 26 +++- scripts/db-truncate | 9 +- 10 files changed, 162 insertions(+), 220 deletions(-) create mode 100644 pkg/factory/domestic_other_prices.go create mode 100644 pkg/factory/domestic_other_prices_test.go diff --git a/pkg/factory/domestic_other_prices.go b/pkg/factory/domestic_other_prices.go new file mode 100644 index 00000000000..b878e926d48 --- /dev/null +++ b/pkg/factory/domestic_other_prices.go @@ -0,0 +1,49 @@ +package factory + +import ( + "database/sql" + "log" + + "github.com/gobuffalo/pop/v6" + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/testdatagen" +) + +func FetchOrMakeDomesticOtherPrice(db *pop.Connection, customs []Customization, traits []Trait) models.ReDomesticOtherPrice { + customs = setupCustomizations(customs, traits) + + var cReDomesticOtherPrice models.ReDomesticOtherPrice + if result := findValidCustomization(customs, ReDomesticOtherPrice); result != nil { + cReDomesticOtherPrice = result.Model.(models.ReDomesticOtherPrice) + if result.LinkOnly { + return cReDomesticOtherPrice + } + } + + // fetch first before creating + // the contractID, serviceID, peak, and schedule need to be unique + var reDomesticOtherPrice models.ReDomesticOtherPrice + if cReDomesticOtherPrice.ContractID != uuid.Nil && cReDomesticOtherPrice.ServiceID != uuid.Nil && cReDomesticOtherPrice.Schedule != 0 { + err := db.Where("contract_id = ? AND service_id = ? AND is_peak_period = ? AND schedule = ?", + cReDomesticOtherPrice.ContractID, + cReDomesticOtherPrice.ServiceID, + cReDomesticOtherPrice.IsPeakPeriod, + cReDomesticOtherPrice.Schedule). + First(&reDomesticOtherPrice) + if err != nil && err != sql.ErrNoRows { + log.Panic(err) + } + return reDomesticOtherPrice + } + + // Overwrite values with those from customizations + testdatagen.MergeModels(&reDomesticOtherPrice, cReDomesticOtherPrice) + + // If db is false, it's a stub. No need to create in database + if db != nil { + mustCreate(db, &reDomesticOtherPrice) + } + return reDomesticOtherPrice +} diff --git a/pkg/factory/domestic_other_prices_test.go b/pkg/factory/domestic_other_prices_test.go new file mode 100644 index 00000000000..a1e0ae08f11 --- /dev/null +++ b/pkg/factory/domestic_other_prices_test.go @@ -0,0 +1,30 @@ +package factory + +import ( + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/unit" +) + +func (suite *FactorySuite) TestFetchOrMakeDomesticOtherPrice() { + suite.Run("Successful fetch of domestic other price", func() { + + id, err := uuid.FromString("51393fa4-b31c-40fe-bedf-b692703c46eb") + suite.NoError(err) + reService := FetchReServiceByCode(suite.DB(), models.ReServiceCodeDLH) + + domesticOtherPrice := FetchOrMakeDomesticOtherPrice(suite.DB(), []Customization{ + { + Model: models.ReDomesticOtherPrice{ + ContractID: id, + ServiceID: reService.ID, + IsPeakPeriod: true, + Schedule: 1, + PriceCents: unit.Cents(945), + }, + }, + }, nil) + suite.NotNil(domesticOtherPrice) + }) +} diff --git a/pkg/factory/shared.go b/pkg/factory/shared.go index bc49aed27ff..b292d1e6e6d 100644 --- a/pkg/factory/shared.go +++ b/pkg/factory/shared.go @@ -80,6 +80,7 @@ var PrimeUpload CustomType = "PrimeUpload" var ProgearWeightTicket CustomType = "ProgearWeightTicket" var ProofOfServiceDoc CustomType = "ProofOfServiceDoc" var ReService CustomType = "ReService" +var ReDomesticOtherPrice CustomType = "ReDomesticOtherPrice" var Role CustomType = "Role" var ServiceItemParamKey CustomType = "ServiceItemParamKey" var ServiceParam CustomType = "ServiceParam" @@ -146,6 +147,7 @@ var defaultTypesMap = map[string]CustomType{ "models.ProgearWeightTicket": ProgearWeightTicket, "models.ProofOfServiceDoc": ProofOfServiceDoc, "models.ReService": ReService, + "models.ReDomesticOtherPrice": ReDomesticOtherPrice, "models.ServiceItemParamKey": ServiceItemParamKey, "models.ServiceMember": ServiceMember, "models.ServiceRequestDocument": ServiceRequestDocument, diff --git a/pkg/services/payment_request/payment_request_creator_test.go b/pkg/services/payment_request/payment_request_creator_test.go index 09b41de1ca7..17aca04b33b 100644 --- a/pkg/services/payment_request/payment_request_creator_test.go +++ b/pkg/services/payment_request/payment_request_creator_test.go @@ -1348,7 +1348,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequestCheckOnNTSRelea testZip3Distance := 1234 // ((testOriginalWeight / 100.0) * testZip3Distance * testDLHRate * testEscalationCompounded) / 1000 - testDLHTotalPrice := unit.Cents(279407) + testDLHTotalPrice := unit.Cents(17485484) // // Test data setup diff --git a/pkg/services/payment_request/payment_request_recalculator_test.go b/pkg/services/payment_request/payment_request_recalculator_test.go index 4ca7922e884..94b21d42e71 100644 --- a/pkg/services/payment_request/payment_request_recalculator_test.go +++ b/pkg/services/payment_request/payment_request_recalculator_test.go @@ -165,7 +165,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() { paymentRequest: &oldPaymentRequest, serviceCode: models.ReServiceCodeDLH, - priceCents: unit.Cents(279407), + priceCents: unit.Cents(17485484), paramsToCheck: []paramMap{ {models.ServiceItemParamNameWeightOriginal, strTestOriginalWeight}, {models.ServiceItemParamNameWeightBilled, strTestOriginalWeight}, @@ -183,7 +183,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() { paymentRequest: &oldPaymentRequest, serviceCode: models.ReServiceCodeDOASIT, - priceCents: unit.Cents(254910), + priceCents: unit.Cents(41633), paramsToCheck: []paramMap{ {models.ServiceItemParamNameWeightOriginal, strTestOriginalWeight}, {models.ServiceItemParamNameWeightBilled, strTestOriginalWeight}, @@ -209,7 +209,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() isNewPaymentRequest: true, paymentRequest: newPaymentRequest, serviceCode: models.ReServiceCodeDLH, - priceCents: unit.Cents(261045), + priceCents: unit.Cents(16336383), paramsToCheck: []paramMap{ {models.ServiceItemParamNameWeightOriginal, strTestChangedOriginalWeight}, {models.ServiceItemParamNameWeightBilled, strTestChangedOriginalWeight}, @@ -229,7 +229,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() isNewPaymentRequest: true, paymentRequest: newPaymentRequest, serviceCode: models.ReServiceCodeDOASIT, - priceCents: unit.Cents(238158), // Price same as before since new weight still in same weight bracket + priceCents: unit.Cents(38897), // Price same as before since new weight still in same weight bracket paramsToCheck: []paramMap{ {models.ServiceItemParamNameWeightOriginal, strTestChangedOriginalWeight}, {models.ServiceItemParamNameWeightBilled, strTestChangedOriginalWeight}, @@ -480,21 +480,6 @@ func (suite *PaymentRequestServiceSuite) setupRecalculateData1() (models.Move, m } suite.MustSave(&domServiceAreaPriceDOP) - // Domestic Pack - dpkService := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDPK) - - // Domestic Other Price - domOtherPriceDPK := models.ReDomesticOtherPrice{ - ContractID: contractYear.Contract.ID, - ServiceID: dpkService.ID, - IsPeakPeriod: false, - Schedule: 2, - PriceCents: recalculateTestDomOtherPrice, - Contract: contractYear.Contract, - Service: dpkService, - } - suite.MustSave(&domOtherPriceDPK) - // Build up a payment request with service item references for creating a payment request. paymentRequestArg := models.PaymentRequest{ MoveTaskOrderID: moveTaskOrder.ID, diff --git a/pkg/services/postal_codes/postal_code_validator_test.go b/pkg/services/postal_codes/postal_code_validator_test.go index 80da05fce2d..13986827a60 100644 --- a/pkg/services/postal_codes/postal_code_validator_test.go +++ b/pkg/services/postal_codes/postal_code_validator_test.go @@ -59,29 +59,10 @@ func (suite *ValidatePostalCodeTestSuite) TestValidatePostalCode() { suite.Contains(err.Error(), "not found in postal_code_to_gblocs") }) - suite.Run("Postal code is not in zip3_distances table", func() { - testPostalCode := "30183" - factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), testPostalCode, "CNNQ") - - valid, err := postalCodeValidator.ValidatePostalCode(suite.AppContextForTest(), testPostalCode) - - suite.False(valid) - suite.Error(err) - suite.IsType(&apperror.UnsupportedPostalCodeError{}, err) - suite.Contains(err.Error(), "not found in zip3_distances") - }) - suite.Run("Contract year cannot be found", func() { testPostalCode := "30183" factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), testPostalCode, "CNNQ") - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: testPostalCode[:3], - ToZip3: "993", - }, - }) - suite.buildContractYear(testdatagen.GHCTestYear - 1) valid, err := postalCodeValidator.ValidatePostalCode(suite.AppContextForTest(), testPostalCode) @@ -91,128 +72,11 @@ func (suite *ValidatePostalCodeTestSuite) TestValidatePostalCode() { suite.IsType(&apperror.UnsupportedPostalCodeError{}, err) suite.Contains(err.Error(), "could not find contract year") }) - - suite.Run("Postal code is not in re_zip3s table", func() { - testPostalCode := "30183" - factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), testPostalCode, "CNNQ") - - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: testPostalCode[:3], - ToZip3: "993", - }, - }) - - suite.buildContractYear(testdatagen.GHCTestYear) - - valid, err := postalCodeValidator.ValidatePostalCode(suite.AppContextForTest(), testPostalCode) - - suite.False(valid) - suite.Error(err) - suite.IsType(&apperror.UnsupportedPostalCodeError{}, err) - suite.Contains(err.Error(), "not found in re_zip3s") - }) - - suite.Run("Postal code is not in re_zip5_rate_areas table", func() { - testPostalCode := "32102" - factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), testPostalCode, "CNNQ") - - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: testPostalCode[:3], - ToZip3: "993", - }, - }) - - reContractYear := suite.buildContractYear(testdatagen.GHCTestYear) - serviceArea := testdatagen.MakeDefaultReDomesticServiceArea(suite.DB()) - testdatagen.MakeReZip3(suite.DB(), testdatagen.Assertions{ - ReZip3: models.ReZip3{ - Zip3: testPostalCode[:3], - Contract: reContractYear.Contract, - DomesticServiceArea: serviceArea, - HasMultipleRateAreas: true, - }, - }) - - valid, err := postalCodeValidator.ValidatePostalCode(suite.AppContextForTest(), testPostalCode) - - suite.False(valid) - suite.Error(err) - suite.IsType(&apperror.UnsupportedPostalCodeError{}, err) - suite.Contains(err.Error(), "not found in re_zip5_rate_areas") - }) - - suite.Run("Valid postal code for zip3 with single rate area", func() { - testPostalCode := "30813" - factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), testPostalCode, "CNNQ") - - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: testPostalCode[:3], - ToZip3: "993", - }, - }) - - reContractYear := suite.buildContractYear(testdatagen.GHCTestYear) - serviceArea := testdatagen.MakeDefaultReDomesticServiceArea(suite.DB()) - testdatagen.MakeReZip3(suite.DB(), testdatagen.Assertions{ - ReZip3: models.ReZip3{ - Zip3: testPostalCode[:3], - Contract: reContractYear.Contract, - DomesticServiceArea: serviceArea, - }, - }) - - valid, err := postalCodeValidator.ValidatePostalCode(suite.AppContextForTest(), testPostalCode) - - suite.True(valid) - suite.NoError(err) - }) - - suite.Run("Valid postal code for zip3 with multiple rate areas", func() { - testPostalCode := "32102" - factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), testPostalCode, "CNNQ") - - testdatagen.MakeZip3Distance(suite.DB(), testdatagen.Assertions{ - Zip3Distance: models.Zip3Distance{ - FromZip3: testPostalCode[:3], - ToZip3: "993", - }, - }) - - reContractYear := suite.buildContractYear(testdatagen.GHCTestYear) - serviceArea := testdatagen.MakeDefaultReDomesticServiceArea(suite.DB()) - testdatagen.MakeReZip3(suite.DB(), testdatagen.Assertions{ - ReZip3: models.ReZip3{ - Zip3: testPostalCode[:3], - Contract: reContractYear.Contract, - DomesticServiceArea: serviceArea, - HasMultipleRateAreas: true, - }, - }) - - rateArea := testdatagen.FetchOrMakeReRateArea(suite.DB(), testdatagen.Assertions{ - ReContractYear: reContractYear, - }) - testdatagen.MakeReZip5RateArea(suite.DB(), testdatagen.Assertions{ - ReZip5RateArea: models.ReZip5RateArea{ - Zip5: testPostalCode, - }, - ReContract: reContractYear.Contract, - ReRateArea: rateArea, - }) - - valid, err := postalCodeValidator.ValidatePostalCode(suite.AppContextForTest(), testPostalCode) - - suite.True(valid) - suite.NoError(err) - }) } func (suite *ValidatePostalCodeTestSuite) buildContractYear(testYear int) models.ReContractYear { - reContract := testdatagen.MakeDefaultReContract(suite.DB()) - reContractYear := testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + reContract := testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + reContractYear := testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ Contract: reContract, StartDate: time.Date(testYear, time.January, 1, 0, 0, 0, 0, time.UTC), diff --git a/pkg/services/ppm_closeout/ppm_closeout_test.go b/pkg/services/ppm_closeout/ppm_closeout_test.go index 0942215fa7c..ac86dee3f04 100644 --- a/pkg/services/ppm_closeout/ppm_closeout_test.go +++ b/pkg/services/ppm_closeout/ppm_closeout_test.go @@ -184,53 +184,42 @@ func (suite *PPMCloseoutSuite) TestPPMShipmentCreator() { dpkService := factory.FetchReServiceByCode(suite.AppContextForTest().DB(), models.ReServiceCodeDPK) - testdatagen.FetchOrMakeReDomesticOtherPrice(suite.AppContextForTest().DB(), testdatagen.Assertions{ - ReDomesticOtherPrice: models.ReDomesticOtherPrice{ - ContractID: originDomesticServiceArea.ContractID, - Contract: originDomesticServiceArea.Contract, - ServiceID: dpkService.ID, - Service: dpkService, - IsPeakPeriod: false, - Schedule: 3, - PriceCents: 7395, + factory.FetchOrMakeDomesticOtherPrice(suite.DB(), []factory.Customization{ + { + Model: models.ReDomesticOtherPrice{ + ContractID: originDomesticServiceArea.ContractID, + ServiceID: dpkService.ID, + IsPeakPeriod: true, + Schedule: 3, + PriceCents: 7395, + }, }, - }) - testdatagen.FetchOrMakeReDomesticOtherPrice(suite.AppContextForTest().DB(), testdatagen.Assertions{ - ReDomesticOtherPrice: models.ReDomesticOtherPrice{ - ContractID: originDomesticServiceArea.ContractID, - Contract: originDomesticServiceArea.Contract, - ServiceID: dpkService.ID, - Service: dpkService, - IsPeakPeriod: true, - Schedule: 3, - PriceCents: 7395, - }, - }) + }, nil) dupkService := factory.FetchReServiceByCode(suite.AppContextForTest().DB(), models.ReServiceCodeDUPK) - testdatagen.FetchOrMakeReDomesticOtherPrice(suite.AppContextForTest().DB(), testdatagen.Assertions{ - ReDomesticOtherPrice: models.ReDomesticOtherPrice{ - ContractID: destDomesticServiceArea.ContractID, - Contract: destDomesticServiceArea.Contract, - ServiceID: dupkService.ID, - Service: dupkService, - IsPeakPeriod: false, - Schedule: 2, - PriceCents: 597, + factory.FetchOrMakeDomesticOtherPrice(suite.DB(), []factory.Customization{ + { + Model: models.ReDomesticOtherPrice{ + ContractID: destDomesticServiceArea.ContractID, + ServiceID: dupkService.ID, + IsPeakPeriod: false, + Schedule: 2, + PriceCents: 597, + }, }, - }) - testdatagen.FetchOrMakeReDomesticOtherPrice(suite.AppContextForTest().DB(), testdatagen.Assertions{ - ReDomesticOtherPrice: models.ReDomesticOtherPrice{ - ContractID: destDomesticServiceArea.ContractID, - Contract: destDomesticServiceArea.Contract, - ServiceID: dupkService.ID, - Service: dupkService, - IsPeakPeriod: true, - Schedule: 2, - PriceCents: 597, + }, nil) + factory.FetchOrMakeDomesticOtherPrice(suite.DB(), []factory.Customization{ + { + Model: models.ReDomesticOtherPrice{ + ContractID: destDomesticServiceArea.ContractID, + ServiceID: dupkService.ID, + IsPeakPeriod: true, + Schedule: 2, + PriceCents: 597, + }, }, - }) + }, nil) dofsitService := factory.FetchReServiceByCode(suite.AppContextForTest().DB(), models.ReServiceCodeDOFSIT) diff --git a/pkg/services/ppmshipment/ppm_estimator_test.go b/pkg/services/ppmshipment/ppm_estimator_test.go index fb8a8adff2b..d4ca213d2ac 100644 --- a/pkg/services/ppmshipment/ppm_estimator_test.go +++ b/pkg/services/ppmshipment/ppm_estimator_test.go @@ -502,15 +502,15 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(unit.Pound(4000), *ppmShipment.EstimatedWeight) - suite.Equal(unit.Cents(37841824), linehaul) + suite.Equal(unit.Cents(43384128), linehaul) suite.Equal(unit.Cents(3004), fuel) - suite.Equal(unit.Cents(16160), origin) + suite.Equal(unit.Cents(21760), origin) suite.Equal(unit.Cents(33280), dest) - suite.Equal(unit.Cents(295800), packing) + suite.Equal(unit.Cents(290000), packing) suite.Equal(unit.Cents(23880), unpacking) total := linehaul + fuel + origin + dest + packing + unpacking - suite.Equal(unit.Cents(38213948), total) + suite.Equal(unit.Cents(43756052), total) }) suite.Run("Estimated Incentive", func() { @@ -548,7 +548,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) suite.Equal(unit.Pound(5000), *newPPM.EstimatedWeight) - suite.Equal(unit.Cents(70064364), *ppmEstimate) + suite.Equal(unit.Cents(80249474), *ppmEstimate) }) suite.Run("Estimated Incentive - Success using db authorize weight and not estimated incentive", func() { @@ -619,7 +619,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) suite.Equal(unit.Pound(5000), *newPPM.EstimatedWeight) - suite.Equal(unit.Cents(70064364), *ppmEstimate) + suite.Equal(unit.Cents(80249474), *ppmEstimate) }) suite.Run("Estimated Incentive - Success when old Estimated Incentive is zero", func() { @@ -653,7 +653,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) suite.Equal(unit.Pound(5000), *newPPM.EstimatedWeight) - suite.Equal(unit.Cents(70064364), *ppmEstimate) + suite.Equal(unit.Cents(80249474), *ppmEstimate) }) suite.Run("Estimated Incentive - Success - clears advance and advance requested values", func() { @@ -684,7 +684,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { suite.NilOrNoVerrs(err) suite.Nil(newPPM.HasRequestedAdvance) suite.Nil(newPPM.AdvanceAmountRequested) - suite.Equal(unit.Cents(38213948), *ppmEstimate) + suite.Equal(unit.Cents(43754569), *ppmEstimate) }) suite.Run("Estimated Incentive - does not change when required fields are the same", func() { @@ -773,7 +773,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { "50309", "30813", false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) - suite.Equal(unit.Cents(112102682), *maxIncentive) + suite.Equal(unit.Cents(128398858), *maxIncentive) }) suite.Run("Max Incentive - Success - is skipped when Estimated Weight is missing", func() { @@ -839,7 +839,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) suite.Equal(unit.Pound(5000), originalWeight) suite.Equal(unit.Pound(5000), newWeight) - suite.Equal(unit.Cents(70064364), *ppmFinal) + suite.Equal(unit.Cents(80249474), *ppmFinal) }) suite.Run("Final Incentive - Success with allowable weight less than net weight", func() { @@ -889,7 +889,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) suite.Equal(unit.Pound(5000), originalWeight) suite.Equal(unit.Pound(5000), newWeight) - suite.Equal(unit.Cents(70064364), *ppmFinal) + suite.Equal(unit.Cents(80249474), *ppmFinal) // Repeat the above shipment with an allowable weight less than the net weight weightOverride = unit.Pound(19500) @@ -996,7 +996,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) suite.Equal(unit.Pound(4000), originalWeight) suite.Equal(unit.Pound(5000), newWeight) - suite.Equal(unit.Cents(70064364), *ppmFinal) + suite.Equal(unit.Cents(80249474), *ppmFinal) }) suite.Run("Final Incentive - Success with disregarding rejected weight tickets", func() { @@ -1113,7 +1113,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) suite.Equal(unit.Pound(8000), originalWeight) suite.Equal(unit.Pound(4000), newWeight) - suite.Equal(unit.Cents(38213948), *ppmFinal) + suite.Equal(unit.Cents(43756052), *ppmFinal) suite.NotEqual(oldPPMShipment.FinalIncentive, *ppmFinal) }) @@ -1183,7 +1183,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) suite.Equal(unit.Pound(8000), originalWeight) suite.Equal(unit.Pound(3000), newWeight) - suite.Equal(unit.Cents(28661212), *ppmFinal) + suite.Equal(unit.Cents(32817790), *ppmFinal) suite.NotEqual(oldPPMShipment.FinalIncentive, *ppmFinal) }) @@ -1672,7 +1672,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { suite.NoError(err) suite.NotNil(estimatedSITCost) - suite.Equal(50660, estimatedSITCost.Int()) + suite.Equal(56660, estimatedSITCost.Int()) }) suite.Run("Success - Destination First Day and Additional Day SIT", func() { diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index e38caadf2df..db6a7a2d146 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -125,8 +125,8 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres suite.Run("Failed distance calculation should error", func() { mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - mock.AnythingOfType("90210"), - mock.AnythingOfType("94535"), + mock.AnythingOfType("string"), + mock.AnythingOfType("string"), false, ).Return(0, fmt.Errorf("error calculating distance 2")).Once() @@ -144,6 +144,28 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres State: "CA", PostalCode: "90210", } + // building DDASIT service item to get dest SIT checks + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + SITDestinationOriginalAddressID: shipment.DestinationAddressID, + }, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeDDASIT, + }, + }, + }, nil) update, err := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) suite.Error(err) suite.Nil(update) diff --git a/scripts/db-truncate b/scripts/db-truncate index 33ad3af6370..341412b4ab0 100755 --- a/scripts/db-truncate +++ b/scripts/db-truncate @@ -11,10 +11,11 @@ BEGIN FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema() AND tablename NOT IN ('us_post_region_cities', 're_countries', 're_states', 're_cities', 're_us_post_regions', 're_oconus_rate_areas', 're_rate_areas', - 're_intl_transit_times', 'ub_allowances','re_services','re_service_items', - 'ports', 'port_locations', 're_fsc_multipliers', 'ghc_diesel_fuel_prices', - 're_zip3s', 'zip3_distances', 're_contracts', 're_domestic_service_areas', - 're_intl_prices', 're_intl_other_prices', 're_domestic_linehaul_prices')) LOOP + 're_intl_transit_times', 'ub_allowances', 're_services', 're_service_items', + 'ports','port_locations', 're_fsc_multipliers', 'ghc_diesel_fuel_prices', + 're_zip3s','zip3_distances', 're_contracts', 're_domestic_service_areas', + 're_intl_prices', 're_intl_other_prices', 're_domestic_linehaul_prices', + 're_domestic_service_area_prices', 're_domestic_other_prices')) LOOP EXECUTE 'TRUNCATE TABLE ' || quote_ident(r.tablename) || ' CASCADE'; END LOOP; END \$\$; From 8e9f6699b543b723b87b12c3c6ede5e2940f919c Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 16:56:58 +0000 Subject: [PATCH 16/52] more pricer test fixes, please save me baby jesus in a tuxedo --- pkg/factory/domestic_service_area_price.go | 45 +++++++++++++++++++ .../domestic_service_area_price_test.go | 38 ++++++++++++++++ pkg/factory/shared.go | 2 + ...c_destination_first_day_sit_pricer_test.go | 4 +- ...ic_destination_sit_delivery_pricer_test.go | 15 ++----- .../domestic_nts_pack_pricer_test.go | 23 +++++----- .../domestic_origin_sit_pickup_pricer_test.go | 8 ++-- .../domestic_pack_pricer_test.go | 4 +- .../domestic_unpack_pricer_test.go | 4 +- .../ghc_rate_engine_service_test.go | 38 +++++++++------- .../ghcrateengine/pricer_helpers_test.go | 6 +-- 11 files changed, 136 insertions(+), 51 deletions(-) create mode 100644 pkg/factory/domestic_service_area_price.go create mode 100644 pkg/factory/domestic_service_area_price_test.go diff --git a/pkg/factory/domestic_service_area_price.go b/pkg/factory/domestic_service_area_price.go new file mode 100644 index 00000000000..ff9110849a8 --- /dev/null +++ b/pkg/factory/domestic_service_area_price.go @@ -0,0 +1,45 @@ +package factory + +import ( + "database/sql" + "log" + + "github.com/gobuffalo/pop/v6" + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/testdatagen" +) + +func FetchOrMakeDomesticServiceAreaPrice(db *pop.Connection, customs []Customization, traits []Trait) models.ReDomesticServiceAreaPrice { + customs = setupCustomizations(customs, traits) + + var cReDomesticServiceAreaPrice models.ReDomesticServiceAreaPrice + if result := findValidCustomization(customs, ReDomesticServiceAreaPrice); result != nil { + cReDomesticServiceAreaPrice = result.Model.(models.ReDomesticServiceAreaPrice) + if result.LinkOnly { + return cReDomesticServiceAreaPrice + } + } + + // fetch first before creating + // the contractID, serviceID, peak, and schedule need to be unique + var reDomesticServiceAreaPrice models.ReDomesticServiceAreaPrice + if cReDomesticServiceAreaPrice.ContractID != uuid.Nil && cReDomesticServiceAreaPrice.ServiceID != uuid.Nil && cReDomesticServiceAreaPrice.DomesticServiceAreaID != uuid.Nil { + err := db.Where("contract_id = ? AND service_id = ? AND domestic_service_area_id = ? AND is_peak_period = ?", + cReDomesticServiceAreaPrice.ContractID, + cReDomesticServiceAreaPrice.ServiceID, + cReDomesticServiceAreaPrice.DomesticServiceAreaID, + cReDomesticServiceAreaPrice.IsPeakPeriod). + First(&reDomesticServiceAreaPrice) + if err != nil && err != sql.ErrNoRows { + log.Panic(err) + } else if err == sql.ErrNoRows { + // if it isn't found, then we need to create it + testdatagen.MergeModels(&reDomesticServiceAreaPrice, cReDomesticServiceAreaPrice) + mustCreate(db, &reDomesticServiceAreaPrice) + } + return reDomesticServiceAreaPrice + } + return reDomesticServiceAreaPrice +} diff --git a/pkg/factory/domestic_service_area_price_test.go b/pkg/factory/domestic_service_area_price_test.go new file mode 100644 index 00000000000..11f0258c8b4 --- /dev/null +++ b/pkg/factory/domestic_service_area_price_test.go @@ -0,0 +1,38 @@ +package factory + +import ( + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" +) + +func (suite *FactorySuite) TestFetchOrMakeDomesticServiceAreaPrice() { + suite.Run("Successful fetch of domestic service area price", func() { + + id, err := uuid.FromString("51393fa4-b31c-40fe-bedf-b692703c46eb") + suite.NoError(err) + reService := FetchReServiceByCode(suite.DB(), models.ReServiceCodeDLH) + serviceArea := testdatagen.FetchOrMakeReDomesticServiceArea(suite.DB(), testdatagen.Assertions{ + ReDomesticServiceArea: models.ReDomesticServiceArea{ + ServiceArea: "004", + ServicesSchedule: 2, + }, + ReContract: testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}), + }) + + domesticServiceAreaPrice := FetchOrMakeDomesticServiceAreaPrice(suite.DB(), []Customization{ + { + Model: models.ReDomesticServiceAreaPrice{ + ContractID: id, + ServiceID: reService.ID, + DomesticServiceAreaID: serviceArea.ID, + IsPeakPeriod: true, + PriceCents: unit.Cents(945), + }, + }, + }, nil) + suite.NotNil(domesticServiceAreaPrice) + }) +} diff --git a/pkg/factory/shared.go b/pkg/factory/shared.go index b292d1e6e6d..33cb656197b 100644 --- a/pkg/factory/shared.go +++ b/pkg/factory/shared.go @@ -81,6 +81,7 @@ var ProgearWeightTicket CustomType = "ProgearWeightTicket" var ProofOfServiceDoc CustomType = "ProofOfServiceDoc" var ReService CustomType = "ReService" var ReDomesticOtherPrice CustomType = "ReDomesticOtherPrice" +var ReDomesticServiceAreaPrice CustomType = "ReDomesticServiceAreaPrice" var Role CustomType = "Role" var ServiceItemParamKey CustomType = "ServiceItemParamKey" var ServiceParam CustomType = "ServiceParam" @@ -148,6 +149,7 @@ var defaultTypesMap = map[string]CustomType{ "models.ProofOfServiceDoc": ProofOfServiceDoc, "models.ReService": ReService, "models.ReDomesticOtherPrice": ReDomesticOtherPrice, + "models.ReDomesticServiceAreaPrice": ReDomesticServiceAreaPrice, "models.ServiceItemParamKey": ServiceItemParamKey, "models.ServiceMember": ServiceMember, "models.ServiceRequestDocument": ServiceRequestDocument, diff --git a/pkg/services/ghcrateengine/domestic_destination_first_day_sit_pricer_test.go b/pkg/services/ghcrateengine/domestic_destination_first_day_sit_pricer_test.go index b3589c58e11..f03ba1e4a53 100644 --- a/pkg/services/ghcrateengine/domestic_destination_first_day_sit_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_destination_first_day_sit_pricer_test.go @@ -14,11 +14,11 @@ import ( const ( ddfsitTestServiceArea = "456" ddfsitTestIsPeakPeriod = false - ddfsitTestBasePriceCents = unit.Cents(525) + ddfsitTestBasePriceCents = unit.Cents(1770) ddfsitTestContractYearName = "DDFSIT Test Year" ddfsitTestEscalationCompounded = 1.052 ddfsitTestWeight = unit.Pound(3300) - ddfsitTestPriceCents = unit.Cents(18216) + ddfsitTestPriceCents = unit.Cents(61446) ) var ddfsitTestRequestedPickupDate = time.Date(testdatagen.TestYear, time.January, 5, 7, 33, 11, 456, time.UTC) diff --git a/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go b/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go index 177839fc54d..25976f78a0d 100644 --- a/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_destination_sit_delivery_pricer_test.go @@ -22,7 +22,7 @@ const ( dddsitTestWeightUpper = unit.Pound(4999) dddsitTestMilesLower = 251 dddsitTestMilesUpper = 500 - dddsitTestDomesticOtherBasePriceCents = unit.Cents(2518) + dddsitTestDomesticOtherBasePriceCents = unit.Cents(21796) dddsitTestDomesticLinehaulBasePriceMillicents = unit.Millicents(237900) dddsitTestDomesticServiceAreaBasePriceCents = unit.Cents(153) ) @@ -35,7 +35,7 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer distance := unit.Miles(37) pricer := NewDomesticDestinationSITDeliveryPricer() - expectedPrice := unit.Cents(58365) // dddsitTestDomesticServiceAreaBasePriceCents * (dddsitTestWeight / 100) * distance * dddsitTestEscalationCompounded + expectedPrice := unit.Cents(505125) // dddsitTestDomesticServiceAreaBasePriceCents * (dddsitTestWeight / 100) * distance * dddsitTestEscalationCompounded suite.Run("success using PaymentServiceItemParams", func() { suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) @@ -49,7 +49,6 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer {Key: models.ServiceItemParamNameContractYearName, Value: dddsitTestContractYearName}, {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(dddsitTestEscalationCompounded)}, {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(dddsitTestIsPeakPeriod)}, - // {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatCents(dddsitTestDomesticServiceAreaBasePriceCents)}, {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatCents(dddsitTestDomesticOtherBasePriceCents)}, } suite.validatePricerCreatedParams(expectedParams, displayParams) @@ -103,14 +102,6 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer suite.Contains(err.Error(), "invalid SIT final destination postal code") }) - suite.Run("bad SIT final destination service area using ServiceAreaLookup", func() { - suite.setupDomesticServiceAreaPrice(models.ReServiceCodeDSH, dddsitTestServiceArea, dddsitTestIsPeakPeriod, dddsitTestDomesticServiceAreaBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) - - _, _, err := pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, dddsitTestRequestedPickupDate, dddsitTestWeight, "111", dddsitTestSchedule, zipDest, zipSITDest, distance) - suite.Error(err) - suite.Contains(err.Error(), "could not fetch domestic destination SIT delivery rate") - }) - suite.Run("error from shorthaul pricer", func() { suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) @@ -168,7 +159,7 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticDestinationSITDeliveryPricer distance := unit.Miles(37) // <= 50 miles pricer := NewDomesticDestinationSITDeliveryPricer() - expectedPrice := unit.Cents(58365) + expectedPrice := unit.Cents(505125) suite.Run("success using PaymentServiceItemParams", func() { suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, dddsitTestContractYearName, dddsitTestEscalationCompounded) diff --git a/pkg/services/ghcrateengine/domestic_nts_pack_pricer_test.go b/pkg/services/ghcrateengine/domestic_nts_pack_pricer_test.go index ce75ab4599c..b3c1c6c441f 100644 --- a/pkg/services/ghcrateengine/domestic_nts_pack_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_nts_pack_pricer_test.go @@ -18,9 +18,9 @@ const ( dnpkTestWeight = unit.Pound(2100) dnpkTestServicesScheduleOrigin = 1 dnpkTestContractYearName = "DNPK Test Year" - dnpkTestBasePriceCents = unit.Cents(6333) + dnpkTestBasePriceCents = unit.Cents(6544) dnpkTestFactor = 1.35 - dnpkTestPriceCents = unit.Cents(186855) + dnpkTestPriceCents = unit.Cents(193064) ) var dnpkTestRequestedPickupDate = time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 5, 5, 5, 5, time.UTC) @@ -116,15 +116,18 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticNTSPackPrices(schedule int, }) packService := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDPK) - otherPrice := models.ReDomesticOtherPrice{ - ContractID: contractYear.Contract.ID, - ServiceID: packService.ID, - IsPeakPeriod: isPeakPeriod, - Schedule: schedule, - PriceCents: priceCents, - } - suite.MustSave(&otherPrice) + factory.FetchOrMakeDomesticOtherPrice(suite.DB(), []factory.Customization{ + { + Model: models.ReDomesticOtherPrice{ + ContractID: contractYear.Contract.ID, + ServiceID: packService.ID, + IsPeakPeriod: isPeakPeriod, + Schedule: schedule, + PriceCents: priceCents, + }, + }, + }, nil) ntsPackService := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDNPK) shipmentTypePrice := models.ReShipmentTypePrice{ diff --git a/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go b/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go index 2fe3c99de4f..cdf36569170 100644 --- a/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_origin_sit_pickup_pricer_test.go @@ -22,9 +22,9 @@ const ( dopsitTestWeightUpper = unit.Pound(4999) dopsitTestMilesLower = 51 dopsitTestMilesUpper = 250 - dopsitTestDomesticOtherBasePriceCents = unit.Cents(2810) + dopsitTestDomesticOtherBasePriceCents = unit.Cents(25030) dopsitTestDomesticLinehaulBasePriceMillicents = unit.Millicents(200300) - dopsitTestDomesticServiceAreaBasePriceCents = unit.Cents(223) + dopsitTestDomesticServiceAreaBasePriceCents = unit.Cents(25030) ) var dopsitTestRequestedPickupDate = time.Date(testdatagen.TestYear, time.July, 5, 10, 22, 11, 456, time.UTC) @@ -35,7 +35,7 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticOriginSITPickupPricerSameZip distance := unit.Miles(12) // distance will follow pricer logic for moves under 50 miles pricer := NewDomesticOriginSITPickupPricer() - expectedPrice := unit.Cents(10613) // dopsitTestDomesticServiceAreaBasePriceCents * (dopsitTestWeight / 100) * distance * dopsitTestEscalationCompounded + expectedPrice := unit.Cents(1190859) // dopsitTestDomesticServiceAreaBasePriceCents * (dopsitTestWeight / 100) * distance * dopsitTestEscalationCompounded suite.Run("success using PaymentServiceItemParams", func() { suite.setupDomesticOtherPrice(models.ReServiceCodeDOPSIT, dopsitTestSchedule, dopsitTestIsPeakPeriod, dopsitTestDomesticServiceAreaBasePriceCents, dopsitTestContractYearName, dopsitTestEscalationCompounded) @@ -154,7 +154,7 @@ func (suite *GHCRateEngineServiceSuite) TestDomesticOriginSITPickupPricer50Miles distance := unit.Miles(23) // <= 50 miles pricer := NewDomesticOriginSITPickupPricer() - expectedPrice := unit.Cents(133689) + expectedPrice := unit.Cents(1190859) suite.Run("success using PaymentServiceItemParams", func() { suite.setupDomesticOtherPrice(models.ReServiceCodeDOPSIT, dopsitTestSchedule, dopsitTestIsPeakPeriod, dopsitTestDomesticOtherBasePriceCents, dopsitTestContractYearName, dopsitTestEscalationCompounded) diff --git a/pkg/services/ghcrateengine/domestic_pack_pricer_test.go b/pkg/services/ghcrateengine/domestic_pack_pricer_test.go index 3939f72c43c..a043c440fa2 100644 --- a/pkg/services/ghcrateengine/domestic_pack_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_pack_pricer_test.go @@ -18,8 +18,8 @@ const ( dpkTestWeight = unit.Pound(2100) dpkTestServicesScheduleOrigin = 1 dpkTestContractYearName = "DPK Test Year" - dpkTestBasePriceCents = unit.Cents(146) - dpkTestPriceCents = unit.Cents(3192) + dpkTestBasePriceCents = unit.Cents(6544) + dpkTestPriceCents = unit.Cents(143010) ) var dpkTestRequestedPickupDate = time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC) diff --git a/pkg/services/ghcrateengine/domestic_unpack_pricer_test.go b/pkg/services/ghcrateengine/domestic_unpack_pricer_test.go index 41b5c834f80..f914f56857c 100644 --- a/pkg/services/ghcrateengine/domestic_unpack_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_unpack_pricer_test.go @@ -18,8 +18,8 @@ const ( dupkTestWeight = unit.Pound(3600) dupkTestServicesScheduleDest = 1 dupkTestContractYearName = "DUPK Test Year" - dupkTestBasePriceCents = unit.Cents(123) - dupkTestPriceCents = unit.Cents(5436) + dupkTestBasePriceCents = unit.Cents(8334) + dupkTestPriceCents = unit.Cents(369360) ) var dupkTestRequestedPickupDate = time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC).AddDate(0, 0, -1) diff --git a/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go b/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go index df07775c20b..8fcd52d9d34 100644 --- a/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go +++ b/pkg/services/ghcrateengine/ghc_rate_engine_service_test.go @@ -48,13 +48,17 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticOtherPrice(code models.ReSe service := factory.FetchReServiceByCode(suite.DB(), code) - otherPrice := models.ReDomesticOtherPrice{ - ContractID: contractYear.Contract.ID, - ServiceID: service.ID, - IsPeakPeriod: isPeakPeriod, - Schedule: schedule, - PriceCents: priceCents, - } + otherPrice := factory.FetchOrMakeDomesticOtherPrice(suite.DB(), []factory.Customization{ + { + Model: models.ReDomesticOtherPrice{ + ContractID: contractYear.Contract.ID, + ServiceID: service.ID, + IsPeakPeriod: isPeakPeriod, + Schedule: schedule, + PriceCents: priceCents, + }, + }, + }, nil) suite.MustSave(&otherPrice) } @@ -100,15 +104,17 @@ func (suite *GHCRateEngineServiceSuite) setupDomesticServiceAreaPrice(code model }, }) - serviceAreaPrice := models.ReDomesticServiceAreaPrice{ - ContractID: contractYear.Contract.ID, - ServiceID: service.ID, - IsPeakPeriod: isPeakPeriod, - DomesticServiceAreaID: serviceArea.ID, - PriceCents: priceCents, - } - - suite.MustSave(&serviceAreaPrice) + factory.FetchOrMakeDomesticServiceAreaPrice(suite.DB(), []factory.Customization{ + { + Model: models.ReDomesticServiceAreaPrice{ + ContractID: contractYear.Contract.ID, + ServiceID: service.ID, + IsPeakPeriod: isPeakPeriod, + DomesticServiceAreaID: serviceArea.ID, + PriceCents: priceCents, + }, + }, + }, nil) } func (suite *GHCRateEngineServiceSuite) setupDomesticLinehaulPrice(serviceAreaCode string, isPeakPeriod bool, weightLower unit.Pound, weightUpper unit.Pound, milesLower int, milesUpper int, priceMillicents unit.Millicents, contractYearName string, escalationCompounded float64) { diff --git a/pkg/services/ghcrateengine/pricer_helpers_test.go b/pkg/services/ghcrateengine/pricer_helpers_test.go index 7e5921c68b2..be3648927e2 100644 --- a/pkg/services/ghcrateengine/pricer_helpers_test.go +++ b/pkg/services/ghcrateengine/pricer_helpers_test.go @@ -253,7 +253,7 @@ func (suite *GHCRateEngineServiceSuite) Test_priceDomesticPickupDeliverySITSameZ suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, dshContractName, dddsitTestEscalationCompounded) priceCents, displayParams, err := priceDomesticPickupDeliverySIT(suite.AppContextForTest(), models.ReServiceCodeDDDSIT, testdatagen.DefaultContractCode, dddsitTestRequestedPickupDate, dddsitTestWeight, dddsitTestServiceArea, dddsitTestSchedule, dshZipDest, dshZipSITDest, dshDistance) suite.NoError(err) - expectedPrice := unit.Cents(58365) // dddsitTestDomesticServiceAreaBasePriceCents * (dddsitTestWeight / 100) * distance * dddsitTestEscalationCompounded + expectedPrice := unit.Cents(505125) // dddsitTestDomesticServiceAreaBasePriceCents * (dddsitTestWeight / 100) * distance * dddsitTestEscalationCompounded suite.Equal(expectedPrice, priceCents) expectedParams := services.PricingDisplayParams{ @@ -338,7 +338,7 @@ func (suite *GHCRateEngineServiceSuite) Test_priceDomesticPickupDeliverySIT50Mil suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, domContractName, dddsitTestEscalationCompounded) priceCents, displayParams, err := priceDomesticPickupDeliverySIT(suite.AppContextForTest(), models.ReServiceCodeDDDSIT, testdatagen.DefaultContractCode, dddsitTestRequestedPickupDate, dddsitTestWeight, dddsitTestServiceArea, dddsitTestSchedule, domOtherZipDest, domOtherZipSITDest, domOtherDistance) suite.NoError(err) - expectedPrice := unit.Cents(58365) + expectedPrice := unit.Cents(505125) suite.Equal(expectedPrice, priceCents) expectedParams := services.PricingDisplayParams{ @@ -378,7 +378,7 @@ func (suite *GHCRateEngineServiceSuite) Test_priceDomesticPickupDeliverySIT50Mil suite.setupDomesticOtherPrice(models.ReServiceCodeDDDSIT, dddsitTestSchedule, dddsitTestIsPeakPeriod, dddsitTestDomesticOtherBasePriceCents, domContractName, dddsitTestEscalationCompounded) priceCents, displayParams, err := priceDomesticPickupDeliverySIT(suite.AppContextForTest(), models.ReServiceCodeDDDSIT, testdatagen.DefaultContractCode, dddsitTestRequestedPickupDate, dddsitTestWeight, dddsitTestServiceArea, dddsitTestSchedule, domOtherZipDest, domOtherZipSITDest, domOtherDistance) suite.NoError(err) - expectedPrice := unit.Cents(58365) + expectedPrice := unit.Cents(505125) suite.Equal(expectedPrice, priceCents) expectedParams := services.PricingDisplayParams{ From c71bac967d4d34cb21186ad2880c79d975c52560 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 17:15:56 +0000 Subject: [PATCH 17/52] flaky test --- src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.test.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.test.jsx b/src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.test.jsx index 84587db4032..568902243d6 100644 --- a/src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.test.jsx +++ b/src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.test.jsx @@ -643,7 +643,7 @@ describe('successful submission of form', () => { await waitFor(() => { expect(mockNavigate).toHaveBeenCalledWith(moveDetailsURL); }); - }); + }, 50000); it('successful submission of form when updating a shipments actual weight but not estimated weight', async () => { usePrimeSimulatorGetMove.mockReturnValue(readyReturnValueWithOneHHG); From b1a2db7e62c266793b912d2d6c568b20c29ff0a1 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 17:19:47 +0000 Subject: [PATCH 18/52] test fixes --- pkg/services/ghcimport/import_re_domestic_other_prices_test.go | 2 +- .../ghcimport/import_re_domestic_service_area_prices_test.go | 2 +- pkg/services/ghcimport/import_re_intl_prices_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/services/ghcimport/import_re_domestic_other_prices_test.go b/pkg/services/ghcimport/import_re_domestic_other_prices_test.go index 8cf12ef8cbd..ca14e7f4ad9 100644 --- a/pkg/services/ghcimport/import_re_domestic_other_prices_test.go +++ b/pkg/services/ghcimport/import_re_domestic_other_prices_test.go @@ -85,7 +85,7 @@ func (suite *GHCRateEngineImportSuite) Test_importREDomesticOtherPricesFailures( func (suite *GHCRateEngineImportSuite) helperVerifyDomesticOtherPrices() { count, err := suite.DB().Count(&models.ReDomesticOtherPrice{}) suite.NoError(err) - suite.Equal(24, count) + suite.Equal(48, count) } func (suite *GHCRateEngineImportSuite) helperCheckDomesticOtherPriceValue() { diff --git a/pkg/services/ghcimport/import_re_domestic_service_area_prices_test.go b/pkg/services/ghcimport/import_re_domestic_service_area_prices_test.go index 7f89bb5f431..955a5ed3e63 100644 --- a/pkg/services/ghcimport/import_re_domestic_service_area_prices_test.go +++ b/pkg/services/ghcimport/import_re_domestic_service_area_prices_test.go @@ -70,7 +70,7 @@ func (suite *GHCRateEngineImportSuite) Test_importREDomesticServiceAreaPricesFai func (suite *GHCRateEngineImportSuite) helperVerifyDomesticServiceAreaPrices() { count, err := suite.DB().Count(&models.ReDomesticServiceAreaPrice{}) suite.NoError(err) - suite.Equal(70, count) + suite.Equal(3234, count) } func (suite *GHCRateEngineImportSuite) helperCheckDomesticServiceAreaPriceValue() { diff --git a/pkg/services/ghcimport/import_re_intl_prices_test.go b/pkg/services/ghcimport/import_re_intl_prices_test.go index 976da15d0ab..ae159e3197d 100644 --- a/pkg/services/ghcimport/import_re_intl_prices_test.go +++ b/pkg/services/ghcimport/import_re_intl_prices_test.go @@ -102,7 +102,7 @@ func (suite *GHCRateEngineImportSuite) Test_getRateAreaIDForKind() { func (suite *GHCRateEngineImportSuite) helperVerifyInternationalPrices() { count, err := suite.DB().Count(&models.ReIntlPrice{}) suite.NoError(err) - suite.Equal(27466406, count) + suite.Equal(46640, count) } func (suite *GHCRateEngineImportSuite) helperCheckInternationalPriceValues() { From cacd86d2fcda4071889f8a0392ab08743e141206 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 18:15:25 +0000 Subject: [PATCH 19/52] adding test for shipment address updates on intl shipments --- .../shipment_address_update_requester.go | 6 +- .../shipment_address_update_requester_test.go | 235 ++++++++++++++++++ 2 files changed, 238 insertions(+), 3 deletions(-) diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index e4e9d426ddf..3c33ac47115 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -565,7 +565,6 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc } } } - if tooApprovalStatus == models.ShipmentAddressUpdateStatusRejected { addressUpdate.Status = models.ShipmentAddressUpdateStatusRejected addressUpdate.OfficeRemarks = &tooRemarks @@ -604,9 +603,10 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc } // if the shipment has an estimated weight, we need to update the service item pricing since we know the distances have changed - // this only applies to international shipments + // this only applies to international shipments that the TOO is approving the address change for if shipment.PrimeEstimatedWeight != nil && - shipment.MarketCode == models.MarketCodeInternational { + shipment.MarketCode == models.MarketCodeInternational && + tooApprovalStatus == models.ShipmentAddressUpdateStatusApproved { // the db proc consumes the mileage needed, so we need to get that first mileage, err := f.planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, true) if err != nil { diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index db6a7a2d146..64d2c0fd46d 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -2,6 +2,7 @@ package shipmentaddressupdate import ( "fmt" + "slices" "time" "github.com/stretchr/testify/mock" @@ -825,6 +826,239 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp suite.Equal(updatedShipment.MarketCode, models.MarketCodeInternational) }) + + suite.Run("Successfully update estiamted pricing on service items when address update is approved by TOO", func() { + ghcDomesticTransitTime := models.GHCDomesticTransitTime{ + MaxDaysTransitTime: 12, + WeightLbsLower: 0, + WeightLbsUpper: 10000, + DistanceMilesLower: 0, + DistanceMilesUpper: 10000, + } + _, _ = suite.DB().ValidateAndCreate(&ghcDomesticTransitTime) + + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + pickupUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "50314") + suite.FatalNoError(err) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &pickupUSPRC.ID, + }, + }, + }, nil) + + destUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + suite.FatalNoError(err) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, + }, + }, + }, nil) + + now := time.Now() + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + PrimeEstimatedWeight: models.PoundPointer(4000), + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + ScheduledPickupDate: &now, + RequestedPickupDate: &now, + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + }, nil) + + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeISLH, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: models.CentPointer(1000), + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: models.CentPointer(1000), + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHUPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: models.CentPointer(1000), + }, + }, + }, nil) + portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: models.CentPointer(1000), + }, + }, + { + Model: portLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfEmbarkation, + }, + }, nil) + + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + ).Return(300, nil) + + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + true, + ).Return(300, nil) + + newDestUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99703") + suite.FatalNoError(err) + factory.BuildShipmentAddressUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: models.Address{ + StreetAddress1: "Cold Ave.", + City: "Fairbanks", + State: "AK", + PostalCode: "99703", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &newDestUSPRC.ID, + }, + Type: &factory.Addresses.NewAddress, + }, + }, []factory.Trait{factory.GetTraitShipmentAddressUpdateRequested}) + + officeRemarks := "Changing to another OCONUS address" + update, err := addressUpdateRequester.ReviewShipmentAddressChange(suite.AppContextForTest(), shipment.ID, "APPROVED", officeRemarks) + + suite.NoError(err) + suite.NotNil(update) + suite.Equal(models.ShipmentAddressUpdateStatusApproved, update.Status) + + // checking out the service items + var serviceItems []models.MTOServiceItem + err = suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", shipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err) + + expectedReserviceCodes := []models.ReServiceCode{ + models.ReServiceCodePOEFSC, + models.ReServiceCodeISLH, + models.ReServiceCodeIHPK, + models.ReServiceCodeIHUPK, + } + + initialPrice := 1000 + suite.Equal(4, len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + actualReServiceCode := serviceItems[i].ReService.Code + suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) + // pricing should not be nil + suite.NotNil(serviceItems[i].PricingEstimate) + // initially we set them all to 1000 and they should all be changed + suite.NotEqual(serviceItems[i].PricingEstimate, &initialPrice) + } + }) } func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUpdateRequestChangedPricing() { @@ -1176,6 +1410,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp suite.Equal(autoRejectionRemark, *shorthaul[0].RejectionReason) suite.Equal(linehaul[0].Status, models.MTOServiceItemStatusApproved) }) + suite.Run("Successfully update shipment and its service items without error", func() { mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), From 34c28b4a114882c4d58388ddd3aeb15a912acf38 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 18:33:42 +0000 Subject: [PATCH 20/52] updating migration get rate area function --- ...de_function_and_update_pricing_proc.up.sql | 59 +++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql index a90addbd0f7..51238d9b48f 100644 --- a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql +++ b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql @@ -40,6 +40,57 @@ RETURNS VARCHAR AS $$ END; $$ LANGUAGE plpgsql; +CREATE OR REPLACE FUNCTION get_rate_area_id( + address_id UUID, + service_item_id UUID, + contract_id uuid, + OUT o_rate_area_id UUID +) +RETURNS UUID AS $$ +DECLARE + is_oconus BOOLEAN; + zip3_value TEXT; +BEGIN + is_oconus := get_is_oconus(address_id); + + IF is_oconus THEN + -- re_oconus_rate_areas if is_oconus is TRUE + SELECT ro.rate_area_id + INTO o_rate_area_id + FROM addresses a + JOIN re_oconus_rate_areas ro + ON a.us_post_region_cities_id = ro.us_post_region_cities_id + JOIN re_rate_areas ra ON ro.rate_area_id = ra.id + WHERE a.id = address_id + AND ra.contract_id = contract_id; + ELSE + -- re_zip3s if is_oconus is FALSE + SELECT rupr.zip3 + INTO zip3_value + FROM addresses a + JOIN us_post_region_cities uprc + ON a.us_post_region_cities_id = uprc.id + JOIN re_us_post_regions rupr + ON uprc.us_post_regions_id = rupr.id + WHERE a.id = address_id; + + -- use the zip3 value to find the rate_area_id in re_zip3s + SELECT rz.rate_area_id + INTO o_rate_area_id + FROM re_zip3s rz + JOIN re_rate_areas ra + ON rz.rate_area_id = ra.id + WHERE rz.zip3 = zip3_value + AND ra.contract_id = contract_id; + END IF; + + -- Raise an exception if no rate area is found + IF o_rate_area_id IS NULL THEN + RAISE EXCEPTION 'Rate area not found for address % for service item ID %', address_id, service_item_id; + END IF; +END; +$$ LANGUAGE plpgsql; + -- updating the pricing proc to now consume the mileage we get from DTOD instead of calculate it using Rand McNally -- this is a requirement for E-06210 CREATE OR REPLACE PROCEDURE update_service_item_pricing( @@ -92,9 +143,9 @@ BEGIN CASE WHEN service_code IN (''ISLH'', ''UBP'') THEN - o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id); - d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id); contract_id := get_contract_id(shipment.requested_pickup_date); + o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id, contract_id); + d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id, contract_id); escalated_price := calculate_escalated_price(o_rate_area_id, d_rate_area_id, service_item.re_service_id, contract_id, service_code); IF shipment.prime_estimated_weight IS NOT NULL THEN @@ -104,8 +155,8 @@ BEGIN WHEN service_code IN (''IHPK'', ''IUBPK'') THEN -- perform IHPK/IUBPK-specific logic (no destination rate area) - o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id); contract_id := get_contract_id(shipment.requested_pickup_date); + o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id, contract_id); escalated_price := calculate_escalated_price(o_rate_area_id, NULL, service_item.re_service_id, contract_id, service_code); IF shipment.prime_estimated_weight IS NOT NULL THEN @@ -115,8 +166,8 @@ BEGIN WHEN service_code IN (''IHUPK'', ''IUBUPK'') THEN -- perform IHUPK/IUBUPK-specific logic (no origin rate area) - d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id); contract_id := get_contract_id(shipment.requested_pickup_date); + d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id, contract_id); escalated_price := calculate_escalated_price(NULL, d_rate_area_id, service_item.re_service_id, contract_id, service_code); IF shipment.prime_estimated_weight IS NOT NULL THEN From 1ffd0f14e3e2bbbedac250a3395ebd40fb84c1c1 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 19:10:19 +0000 Subject: [PATCH 21/52] fixing to less ambiguous var name in proc --- ...ate_get_zip_code_function_and_update_pricing_proc.up.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql index 51238d9b48f..8f119836468 100644 --- a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql +++ b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql @@ -43,7 +43,7 @@ $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION get_rate_area_id( address_id UUID, service_item_id UUID, - contract_id uuid, + c_id uuid, OUT o_rate_area_id UUID ) RETURNS UUID AS $$ @@ -62,7 +62,7 @@ BEGIN ON a.us_post_region_cities_id = ro.us_post_region_cities_id JOIN re_rate_areas ra ON ro.rate_area_id = ra.id WHERE a.id = address_id - AND ra.contract_id = contract_id; + AND ra.contract_id = c_id; ELSE -- re_zip3s if is_oconus is FALSE SELECT rupr.zip3 @@ -81,7 +81,7 @@ BEGIN JOIN re_rate_areas ra ON rz.rate_area_id = ra.id WHERE rz.zip3 = zip3_value - AND ra.contract_id = contract_id; + AND ra.contract_id = c_id; END IF; -- Raise an exception if no rate area is found From edf96f2d80dd665628f03a3316e1d14dd570275c Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 21:44:26 +0000 Subject: [PATCH 22/52] updating logic to use port instead of address ZIPs, adding boolean to zip distance looker upper please save me lord --- ...de_function_and_update_pricing_proc.up.sql | 28 ++++++++ pkg/handlers/adminapi/moves_test.go | 1 + pkg/handlers/ghcapi/move_task_order_test.go | 4 ++ pkg/handlers/ghcapi/mto_service_items_test.go | 4 ++ pkg/handlers/ghcapi/mto_shipment_test.go | 21 ++++++ pkg/handlers/ghcapi/orders_test.go | 1 + pkg/handlers/ghcapi/ppm_shipment_test.go | 2 +- pkg/handlers/internalapi/mto_shipment_test.go | 1 + pkg/handlers/primeapi/move_task_order_test.go | 2 + .../primeapi/mto_service_item_test.go | 18 ++++++ .../primeapi/mto_shipment_address_test.go | 1 + pkg/handlers/primeapi/mto_shipment_test.go | 3 + pkg/handlers/primeapi/payment_request_test.go | 3 + pkg/handlers/primeapi/reweigh_test.go | 1 + .../primeapiv2/mto_service_item_test.go | 16 +++++ pkg/handlers/primeapiv2/mto_shipment_test.go | 1 + .../primeapiv3/mto_service_item_test.go | 17 +++++ pkg/handlers/primeapiv3/mto_shipment_test.go | 1 + .../supportapi/move_task_order_test.go | 2 + .../supportapi/mto_service_item_test.go | 3 + pkg/handlers/supportapi/mto_shipment_test.go | 1 + pkg/models/mto_shipments.go | 27 ++++++++ .../distance_zip_lookup.go | 4 +- .../distance_zip_lookup_test.go | 6 +- .../distance_zip_sit_dest_lookup.go | 2 +- .../distance_zip_sit_dest_lookup_test.go | 1 + .../distance_zip_sit_origin_lookup.go | 2 +- .../distance_zip_sit_origin_lookup_test.go | 1 + .../service_param_value_lookups_test.go | 1 + pkg/route/dtod_planner.go | 2 +- pkg/route/dtod_planner_test.go | 4 +- pkg/route/here_planner.go | 2 +- pkg/route/hhg_planner.go | 27 ++++---- pkg/route/hhg_planner_test.go | 8 +-- pkg/route/mocks/Planner.go | 18 +++--- pkg/route/planner.go | 2 +- pkg/route/planner_test.go | 2 +- .../move_history/move_history_fetcher_test.go | 3 + .../move_task_order_updater_test.go | 6 ++ .../mto_service_item_creator.go | 10 +-- .../mto_service_item_creator_test.go | 11 ++++ .../mto_service_item_updater.go | 6 +- .../mto_service_item_updater_test.go | 12 ++++ .../mto_shipment_address_updater.go | 4 +- .../mto_shipment_address_updater_test.go | 2 + .../mto_shipment/mto_shipment_updater.go | 36 ++++++++--- .../mto_shipment/mto_shipment_updater_test.go | 4 ++ .../mto_shipment/shipment_approver.go | 28 ++++++-- .../mto_shipment/shipment_approver_test.go | 8 +++ .../mto_shipment/shipment_deleter_test.go | 2 + .../payment_request_creator_test.go | 3 + .../payment_request_recalculator_test.go | 2 + ...yment_request_shipment_recalculate_test.go | 2 + .../ppm_closeout/ppm_closeout_test.go | 4 +- .../ppmshipment/ppm_estimator_test.go | 64 +++++++++---------- .../ppmshipment/ppm_shipment_updater_test.go | 4 +- pkg/services/reweigh/reweigh_updater_test.go | 1 + .../shipment_address_update_requester.go | 40 +++++++++--- .../shipment_address_update_requester_test.go | 30 +++++++++ .../sit_extension/sit_extension_denier.go | 1 + pkg/testdatagen/scenario/shared.go | 26 +++++--- pkg/testdatagen/testharness/make_move.go | 4 +- 62 files changed, 433 insertions(+), 120 deletions(-) diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql index 8f119836468..a6fd4534b5e 100644 --- a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql +++ b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql @@ -40,6 +40,8 @@ RETURNS VARCHAR AS $$ END; $$ LANGUAGE plpgsql; + +-- updating the get rate area function to include the contract id CREATE OR REPLACE FUNCTION get_rate_area_id( address_id UUID, service_item_id UUID, @@ -93,6 +95,7 @@ $$ LANGUAGE plpgsql; -- updating the pricing proc to now consume the mileage we get from DTOD instead of calculate it using Rand McNally -- this is a requirement for E-06210 +-- also updating the get_rate_area parameters and passing in the contract_id CREATE OR REPLACE PROCEDURE update_service_item_pricing( shipment_id UUID, mileage INT @@ -204,3 +207,28 @@ BEGIN END; ' LANGUAGE plpgsql; + +-- this function will help us get the ZIP code & port type for a port to calculate mileage +CREATE OR REPLACE FUNCTION get_port_location_info_for_shipment(shipment_id UUID) +RETURNS TABLE(uspr_zip_id TEXT, port_type TEXT) AS $$ +BEGIN + -- select the ZIP code and port type (POEFSC or PODFSC) + RETURN QUERY + SELECT + COALESCE(poe_usprc.uspr_zip_id::TEXT, pod_usprc.uspr_zip_id::TEXT) AS uspr_zip_id, + CASE + WHEN msi.poe_location_id IS NOT NULL THEN 'POEFSC' + WHEN msi.pod_location_id IS NOT NULL THEN 'PODFSC' + ELSE NULL + END AS port_type + FROM mto_shipments ms + JOIN mto_service_items msi ON ms.id = msi.mto_shipment_id + LEFT JOIN port_locations poe_pl ON msi.poe_location_id = poe_pl.id + LEFT JOIN port_locations pod_pl ON msi.pod_location_id = pod_pl.id + LEFT JOIN us_post_region_cities poe_usprc ON poe_pl.us_post_region_cities_id = poe_usprc.id + LEFT JOIN us_post_region_cities pod_usprc ON pod_pl.us_post_region_cities_id = pod_usprc.id + WHERE ms.id = shipment_id + AND (msi.poe_location_id IS NOT NULL OR msi.pod_location_id IS NOT NULL) + LIMIT 1; +END; +$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/pkg/handlers/adminapi/moves_test.go b/pkg/handlers/adminapi/moves_test.go index dfeabc2ee36..bfc3291df46 100644 --- a/pkg/handlers/adminapi/moves_test.go +++ b/pkg/handlers/adminapi/moves_test.go @@ -118,6 +118,7 @@ func (suite *HandlerSuite) TestUpdateMoveHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) return UpdateMoveHandler{ suite.HandlerConfig(), diff --git a/pkg/handlers/ghcapi/move_task_order_test.go b/pkg/handlers/ghcapi/move_task_order_test.go index 5668b881713..e93d756cf58 100644 --- a/pkg/handlers/ghcapi/move_task_order_test.go +++ b/pkg/handlers/ghcapi/move_task_order_test.go @@ -190,6 +190,7 @@ func (suite *HandlerSuite) TestUpdateMoveTaskOrderHandlerIntegrationSuccess() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -315,6 +316,7 @@ func (suite *HandlerSuite) TestUpdateMoveTaskOrderHandlerIntegrationWithIncomple mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -404,6 +406,7 @@ func (suite *HandlerSuite) TestUpdateMTOStatusServiceCounselingCompletedHandler( mock.Anything, mock.Anything, false, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := UpdateMTOStatusServiceCounselingCompletedHandlerFunc{ @@ -624,6 +627,7 @@ func (suite *HandlerSuite) TestUpdateMoveTIORemarksHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/ghcapi/mto_service_items_test.go b/pkg/handlers/ghcapi/mto_service_items_test.go index d7b850f1bb4..23071c64635 100644 --- a/pkg/handlers/ghcapi/mto_service_items_test.go +++ b/pkg/handlers/ghcapi/mto_service_items_test.go @@ -313,6 +313,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -566,6 +567,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) mtoServiceItemStatusUpdater := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -628,6 +630,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) mtoServiceItemStatusUpdater := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -763,6 +766,7 @@ func (suite *HandlerSuite) TestUpdateServiceItemSitEntryDateHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) diff --git a/pkg/handlers/ghcapi/mto_shipment_test.go b/pkg/handlers/ghcapi/mto_shipment_test.go index 712a4878a09..03096892d58 100644 --- a/pkg/handlers/ghcapi/mto_shipment_test.go +++ b/pkg/handlers/ghcapi/mto_shipment_test.go @@ -604,6 +604,7 @@ func (suite *HandlerSuite) TestApproveShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) approver := mtoshipment.NewShipmentApprover( mtoshipment.NewShipmentRouter(), @@ -2125,6 +2126,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2184,6 +2186,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2240,6 +2243,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2297,6 +2301,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2355,6 +2360,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2412,6 +2418,7 @@ func (suite *HandlerSuite) TestRequestShipmentReweighHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2751,6 +2758,7 @@ func (suite *HandlerSuite) TestApproveSITExtensionHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2892,6 +2900,7 @@ func (suite *HandlerSuite) CreateApprovedSITDurationUpdate() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -2976,6 +2985,7 @@ func (suite *HandlerSuite) CreateApprovedSITDurationUpdate() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -3150,6 +3160,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3235,6 +3246,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3292,6 +3304,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3345,6 +3358,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3393,6 +3407,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3478,6 +3493,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerUsingPPM() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( @@ -3690,6 +3706,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerUsingPPM() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -3841,6 +3858,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerUsingPPM() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveTaskOrderUpdater := movetaskorder.NewMoveTaskOrderUpdater( builder, @@ -4047,6 +4065,7 @@ func (suite *HandlerSuite) TestUpdateShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(mtoshipment.NewShipmentReweighRequester()) @@ -4718,6 +4737,7 @@ func (suite *HandlerSuite) TestUpdateSITServiceItemCustomerExpenseHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) updater := mtoserviceitem.NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) req := httptest.NewRequest("PATCH", fmt.Sprintf("/shipments/%s/sit-service-item/convert-to-customer-expense", approvedShipment.ID.String()), nil) @@ -4795,6 +4815,7 @@ func (suite *HandlerSuite) TestUpdateSITServiceItemCustomerExpenseHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) updater := mtoserviceitem.NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) req := httptest.NewRequest("PATCH", fmt.Sprintf("/shipments/%s/sit-service-item/convert-to-customer-expense", approvedShipment.ID.String()), nil) diff --git a/pkg/handlers/ghcapi/orders_test.go b/pkg/handlers/ghcapi/orders_test.go index 4be34b50c1e..6d3bd880903 100644 --- a/pkg/handlers/ghcapi/orders_test.go +++ b/pkg/handlers/ghcapi/orders_test.go @@ -399,6 +399,7 @@ func (suite *HandlerSuite) TestUpdateOrderHandlerWithAmendedUploads() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/ghcapi/ppm_shipment_test.go b/pkg/handlers/ghcapi/ppm_shipment_test.go index d2d050b8393..d5e358feb4a 100644 --- a/pkg/handlers/ghcapi/ppm_shipment_test.go +++ b/pkg/handlers/ghcapi/ppm_shipment_test.go @@ -388,7 +388,7 @@ func (suite *HandlerSuite) TestGetPPMSITEstimatedCostHandler() { ppmShipment.DestinationAddress = destinationAddress mockedPlanner := &routemocks.Planner{} mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813", false).Return(2294, nil) + "90210", "30813", false, false).Return(2294, nil) }) setUpGetCostRequestAndParams := func() ppmsitops.GetPPMSITEstimatedCostParams { diff --git a/pkg/handlers/internalapi/mto_shipment_test.go b/pkg/handlers/internalapi/mto_shipment_test.go index 3e43ee91955..f227a704629 100644 --- a/pkg/handlers/internalapi/mto_shipment_test.go +++ b/pkg/handlers/internalapi/mto_shipment_test.go @@ -78,6 +78,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandlerV1() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapi/move_task_order_test.go b/pkg/handlers/primeapi/move_task_order_test.go index 5f79f53584e..b659b9386d9 100644 --- a/pkg/handlers/primeapi/move_task_order_test.go +++ b/pkg/handlers/primeapi/move_task_order_test.go @@ -1711,6 +1711,7 @@ func (suite *HandlerSuite) TestUpdateMTOPostCounselingInfo() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -1796,6 +1797,7 @@ func (suite *HandlerSuite) TestUpdateMTOPostCounselingInfo() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapi/mto_service_item_test.go b/pkg/handlers/primeapi/mto_service_item_test.go index 8ad036e79fa..c1b8b9d7800 100644 --- a/pkg/handlers/primeapi/mto_service_item_test.go +++ b/pkg/handlers/primeapi/mto_service_item_test.go @@ -95,6 +95,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -154,6 +155,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -293,6 +295,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -338,6 +341,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -490,6 +494,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -528,6 +533,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -652,6 +658,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -699,6 +706,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -769,6 +777,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -854,6 +863,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITNoA mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -965,6 +975,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITWit mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1139,6 +1150,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1214,6 +1226,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1248,6 +1261,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1305,6 +1319,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1360,6 +1375,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1559,6 +1575,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemDDDSIT() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) subtestData.handler = UpdateMTOServiceItemHandler{ suite.HandlerConfig(), @@ -1843,6 +1860,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemDOPSIT() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) subtestData.handler = UpdateMTOServiceItemHandler{ suite.HandlerConfig(), diff --git a/pkg/handlers/primeapi/mto_shipment_address_test.go b/pkg/handlers/primeapi/mto_shipment_address_test.go index 71235074946..cb662b28dfe 100644 --- a/pkg/handlers/primeapi/mto_shipment_address_test.go +++ b/pkg/handlers/primeapi/mto_shipment_address_test.go @@ -48,6 +48,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentAddressHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) // Create handler handler := UpdateMTOShipmentAddressHandler{ diff --git a/pkg/handlers/primeapi/mto_shipment_test.go b/pkg/handlers/primeapi/mto_shipment_test.go index 4581aa59487..917e10cdfc6 100644 --- a/pkg/handlers/primeapi/mto_shipment_test.go +++ b/pkg/handlers/primeapi/mto_shipment_test.go @@ -204,6 +204,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentStatusHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) moveRouter := moveservices.NewMoveRouter() addressUpdater := address.NewAddressUpdater() @@ -225,6 +226,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentStatusHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) handler := UpdateMTOShipmentStatusHandler{ handlerConfig, @@ -417,6 +419,7 @@ func (suite *HandlerSuite) TestDeleteMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapi/payment_request_test.go b/pkg/handlers/primeapi/payment_request_test.go index 5926d8ffbf8..768e10c0033 100644 --- a/pkg/handlers/primeapi/payment_request_test.go +++ b/pkg/handlers/primeapi/payment_request_test.go @@ -747,6 +747,7 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerNewPaymentRequestCreat "90210", "94535", false, + false, ).Return(defaultZipDistance, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( @@ -907,6 +908,7 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerInvalidMTOReferenceID( "90210", "94535", false, + false, ).Return(defaultZipDistance, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( @@ -973,6 +975,7 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerInvalidMTOReferenceID( "90210", "94535", false, + false, ).Return(defaultZipDistance, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( diff --git a/pkg/handlers/primeapi/reweigh_test.go b/pkg/handlers/primeapi/reweigh_test.go index 6603dcb1c68..d97b7f78d22 100644 --- a/pkg/handlers/primeapi/reweigh_test.go +++ b/pkg/handlers/primeapi/reweigh_test.go @@ -37,6 +37,7 @@ func (suite *HandlerSuite) TestUpdateReweighHandler() { recalculateTestPickupZip, recalculateTestDestinationZip, false, + false, ).Return(recalculateTestZip3Distance, nil) // Get shipment payment request recalculator service diff --git a/pkg/handlers/primeapiv2/mto_service_item_test.go b/pkg/handlers/primeapiv2/mto_service_item_test.go index 8fc984d4daa..0a36349c110 100644 --- a/pkg/handlers/primeapiv2/mto_service_item_test.go +++ b/pkg/handlers/primeapiv2/mto_service_item_test.go @@ -89,6 +89,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -148,6 +149,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -287,6 +289,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -332,6 +335,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -484,6 +488,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -522,6 +527,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -646,6 +652,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -693,6 +700,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -763,6 +771,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -848,6 +857,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITNoA mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -957,6 +967,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITWit mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1125,6 +1136,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1200,6 +1212,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1234,6 +1247,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1291,6 +1305,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1356,6 +1371,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ diff --git a/pkg/handlers/primeapiv2/mto_shipment_test.go b/pkg/handlers/primeapiv2/mto_shipment_test.go index 83134e3b522..aaf6ba180d6 100644 --- a/pkg/handlers/primeapiv2/mto_shipment_test.go +++ b/pkg/handlers/primeapiv2/mto_shipment_test.go @@ -53,6 +53,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/primeapiv3/mto_service_item_test.go b/pkg/handlers/primeapiv3/mto_service_item_test.go index 7ea19fef6f3..ca480bc2c45 100644 --- a/pkg/handlers/primeapiv3/mto_service_item_test.go +++ b/pkg/handlers/primeapiv3/mto_service_item_test.go @@ -88,6 +88,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) subtestData := makeSubtestData() moveRouter := moverouter.NewMoveRouter() @@ -149,6 +150,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -288,6 +290,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -333,6 +336,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -485,6 +489,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -523,6 +528,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDomesticCratingHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -647,6 +653,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -694,6 +701,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -764,6 +772,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -849,6 +858,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITNoA mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -958,6 +968,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemOriginSITHandlerWithDOFSITWit mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1126,6 +1137,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1201,6 +1213,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1235,6 +1248,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1292,6 +1306,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1357,6 +1372,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ @@ -1394,6 +1410,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemDestSITHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) handler := CreateMTOServiceItemHandler{ diff --git a/pkg/handlers/primeapiv3/mto_shipment_test.go b/pkg/handlers/primeapiv3/mto_shipment_test.go index 83f71196d6b..308bdf4d462 100644 --- a/pkg/handlers/primeapiv3/mto_shipment_test.go +++ b/pkg/handlers/primeapiv3/mto_shipment_test.go @@ -59,6 +59,7 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/supportapi/move_task_order_test.go b/pkg/handlers/supportapi/move_task_order_test.go index 1c219d99a70..b1241de3f32 100644 --- a/pkg/handlers/supportapi/move_task_order_test.go +++ b/pkg/handlers/supportapi/move_task_order_test.go @@ -174,6 +174,7 @@ func (suite *HandlerSuite) TestMakeMoveAvailableHandlerIntegrationSuccess() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -390,6 +391,7 @@ func (suite *HandlerSuite) TestCreateMoveTaskOrderRequestHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/handlers/supportapi/mto_service_item_test.go b/pkg/handlers/supportapi/mto_service_item_test.go index 0e3faa635cd..4c0596523a4 100644 --- a/pkg/handlers/supportapi/mto_service_item_test.go +++ b/pkg/handlers/supportapi/mto_service_item_test.go @@ -86,6 +86,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandlerApproveSuccess() mock.Anything, mock.Anything, false, + false, ).Return(400, nil) handler := UpdateMTOServiceItemStatusHandler{handlerConfig, mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher), @@ -144,6 +145,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandlerRejectSuccess() mock.Anything, mock.Anything, false, + false, ).Return(400, nil) handler := UpdateMTOServiceItemStatusHandler{handlerConfig, mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher), @@ -202,6 +204,7 @@ func (suite *HandlerSuite) TestUpdateMTOServiceItemStatusHandlerRejectionFailedN mock.Anything, mock.Anything, false, + false, ).Return(400, nil) handler := UpdateMTOServiceItemStatusHandler{handlerConfig, mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher), diff --git a/pkg/handlers/supportapi/mto_shipment_test.go b/pkg/handlers/supportapi/mto_shipment_test.go index 1a12aff8ced..9a3a0c07a85 100644 --- a/pkg/handlers/supportapi/mto_shipment_test.go +++ b/pkg/handlers/supportapi/mto_shipment_test.go @@ -98,6 +98,7 @@ func (suite *HandlerSuite) TestUpdateMTOShipmentStatusHandler() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) planner.On("Zip5TransitDistanceLineHaul", diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index 7a6d386f945..f832d3f4563 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -361,6 +361,33 @@ func DetermineMarketCode(address1 *Address, address2 *Address) (MarketCode, erro } } +// PortLocationInfo holds the ZIP code and port type for a shipment +// this is used in the db function/query below +type PortLocationInfo struct { + UsprZipID string `db:"uspr_zip_id"` + PortType string `db:"port_type"` +} + +// GetPortLocationForShipment gets the ZIP and port type associated with the port for the POEFSC/PODFSC service item in a shipment +func GetPortLocationInfoForShipment(db *pop.Connection, shipmentID uuid.UUID) (*string, *string, error) { + var portLocationInfo PortLocationInfo + + err := db.RawQuery("SELECT * FROM get_port_location_info_for_shipment($1)", shipmentID). + First(&portLocationInfo) + + if err != nil { + return nil, nil, fmt.Errorf("error fetching port location for shipment ID: %s with error %w", shipmentID, err) + } + + // return the ZIP code and port type, or nil if not found + if portLocationInfo.UsprZipID != "" && portLocationInfo.PortType != "" { + return &portLocationInfo.UsprZipID, &portLocationInfo.PortType, nil + } + + // if nothing was found, return nil - just means we don't have the port info from Prime yet + return nil, nil, nil +} + func CreateApprovedServiceItemsForShipment(db *pop.Connection, shipment *MTOShipment) error { err := db.RawQuery("CALL create_approved_service_items_for_shipment($1)", shipment.ID).Exec() if err != nil { diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go index 98cbb647775..7b70c559d1d 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go @@ -83,7 +83,7 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service } if mtoShipment.DeliveryAddressUpdate != nil && mtoShipment.DeliveryAddressUpdate.Status == models.ShipmentAddressUpdateStatusApproved { - distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, mtoShipment.DeliveryAddressUpdate.NewAddress.PostalCode, false) + distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, mtoShipment.DeliveryAddressUpdate.NewAddress.PostalCode, false, false) if err != nil { return "", err } @@ -98,7 +98,7 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service if pickupZip == destinationZip { distanceMiles = 1 } else { - distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false) + distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false, false) if err != nil { return "", err } diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go index 4168c42bd37..f40692f2f1c 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go @@ -79,7 +79,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() { suite.NoError(err) planner := suite.planner.(*mocks.Planner) - planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode, false) + planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode, false, false) err = suite.DB().Reload(&ppmShipment.Shipment) suite.NoError(err) @@ -110,7 +110,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() { suite.NoError(err) planner := suite.planner.(*mocks.Planner) - planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode, false) + planner.AssertCalled(suite.T(), "ZipTransitDistance", appContext, ppmShipment.PickupAddress.PostalCode, ppmShipment.DestinationAddress.PostalCode, false, false) err = suite.DB().Reload(&ppmShipment.Shipment) suite.NoError(err) @@ -143,7 +143,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() { suite.NoError(err) planner := suite.planner.(*mocks.Planner) - planner.AssertNotCalled(suite.T(), "ZipTransitDistance", appContext, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode) + planner.AssertNotCalled(suite.T(), "ZipTransitDistance", appContext, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, false, false) err = suite.DB().Reload(&shipment) suite.NoError(err) diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go index bc3e612c811..7ddc8651946 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup.go @@ -33,7 +33,7 @@ func (r DistanceZipSITDestLookup) lookup(appCtx appcontext.AppContext, keyData * if destZip == finalDestZip { distanceMiles = 1 } else { - distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, destZip, finalDestZip, false) + distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, destZip, finalDestZip, false, false) } if distanceErr != nil { diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go index c0e29027758..997fcb409e7 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_dest_lookup_test.go @@ -212,6 +212,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceZipSITDestLookup() { mock.Anything, mock.Anything, false, + false, ).Return(0, errors.New("error with ZipTransitDistance")) paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), errorPlanner, mtoServiceItemSameZip3, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go index 945462236dd..52178be8d65 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup.go @@ -39,7 +39,7 @@ func (r DistanceZipSITOriginLookup) lookup(appCtx appcontext.AppContext, keyData if originZip == actualOriginZip { distanceMiles = 1 } else { - distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, originZip, actualOriginZip, false) + distanceMiles, distanceErr = planner.ZipTransitDistance(appCtx, originZip, actualOriginZip, false, false) } if distanceErr != nil { return "", distanceErr diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go index eabf098155f..6c055f7fd6b 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_sit_origin_lookup_test.go @@ -185,6 +185,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceZipSITOriginLookup() { mock.Anything, mock.Anything, false, + false, ).Return(0, errors.New("error with ZipTransitDistance")) paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), errorPlanner, mtoServiceItemSameZip3, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) diff --git a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go index 01767a6591b..1c9138e51ee 100644 --- a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go +++ b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go @@ -47,6 +47,7 @@ func TestServiceParamValueLookupsSuite(t *testing.T) { mock.Anything, mock.Anything, false, + false, ).Return(defaultZipDistance, nil) ts := &ServiceParamValueLookupsSuite{ diff --git a/pkg/route/dtod_planner.go b/pkg/route/dtod_planner.go index b8391c70bbb..61cf7addb26 100644 --- a/pkg/route/dtod_planner.go +++ b/pkg/route/dtod_planner.go @@ -44,7 +44,7 @@ func (p *dtodPlanner) Zip3TransitDistance(_ appcontext.AppContext, _ string, _ s } // ZipTransitDistance calculates the distance between two valid Zips -func (p *dtodPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) { +func (p *dtodPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool, isInternationalShipment bool) (int, error) { if len(source) < 5 { source = fmt.Sprintf("%05s", source) } diff --git a/pkg/route/dtod_planner_test.go b/pkg/route/dtod_planner_test.go index 02e811e31d4..1315f531fc6 100644 --- a/pkg/route/dtod_planner_test.go +++ b/pkg/route/dtod_planner_test.go @@ -100,7 +100,7 @@ func (suite *GHCTestSuite) TestDTODZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewDTODPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false) + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false, false) suite.NoError(err) suite.Equal(150, distance) }) @@ -114,7 +114,7 @@ func (suite *GHCTestSuite) TestDTODZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewDTODPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901", false) + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901", false, false) suite.Error(err) suite.Equal(0, distance) }) diff --git a/pkg/route/here_planner.go b/pkg/route/here_planner.go index aea2b861639..e7114dd1bf2 100644 --- a/pkg/route/here_planner.go +++ b/pkg/route/here_planner.go @@ -219,7 +219,7 @@ func (p *herePlanner) Zip5TransitDistance(appCtx appcontext.AppContext, source s } // ZipTransitDistance calculates the distance between two valid Zip5s; it is used by the PPM flow -func (p *herePlanner) ZipTransitDistance(_ appcontext.AppContext, _ string, _ string, _ bool) (int, error) { +func (p *herePlanner) ZipTransitDistance(_ appcontext.AppContext, _ string, _ string, _ bool, _ bool) (int, error) { // This might get retired after we transition over fully to GHC. panic("implement me") diff --git a/pkg/route/hhg_planner.go b/pkg/route/hhg_planner.go index 5f9fa3f7044..88e1caa04a5 100644 --- a/pkg/route/hhg_planner.go +++ b/pkg/route/hhg_planner.go @@ -46,7 +46,7 @@ func (p *hhgPlanner) Zip3TransitDistance(_ appcontext.AppContext, _ string, _ st } // ZipTransitDistance calculates the distance between two valid Zips -func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) { +func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool, isInternationalShipment bool) (int, error) { sourceZip5 := source if len(source) < 5 { sourceZip5 = fmt.Sprintf("%05s", source) @@ -67,18 +67,21 @@ func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source str // Get reZip3s for origin and destination to compare base point cities. // Dont throw/return errors from this. If we dont find them, we'll just use randMcNallyZip3Distance - sourceReZip3, sErr := models.FetchReZip3Item(appCtx.DB(), sourceZip3) - if sErr != nil { - appCtx.Logger().Error("Failed to fetch the reZip3 item for sourceZip3", zap.Error(sErr)) - } - destinationReZip3, dErr := models.FetchReZip3Item(appCtx.DB(), destZip3) - if dErr != nil { - appCtx.Logger().Error("Failed to fetch the reZip3 item for destinationZip3", zap.Error(dErr)) - } + // this only applies to domestic shipments + if !isInternationalShipment { + sourceReZip3, sErr := models.FetchReZip3Item(appCtx.DB(), sourceZip3) + if sErr != nil { + appCtx.Logger().Error("Failed to fetch the reZip3 item for sourceZip3", zap.Error(sErr)) + } + destinationReZip3, dErr := models.FetchReZip3Item(appCtx.DB(), destZip3) + if dErr != nil { + appCtx.Logger().Error("Failed to fetch the reZip3 item for destinationZip3", zap.Error(dErr)) + } - // Different zip3, same base point city, use DTOD - if sourceReZip3 != nil && destinationReZip3 != nil && sourceReZip3.BasePointCity == destinationReZip3.BasePointCity { - return p.dtodPlannerMileage.DTODZip5Distance(appCtx, source, destination) + // Different zip3, same base point city, use DTOD + if sourceReZip3 != nil && destinationReZip3 != nil && sourceReZip3.BasePointCity == destinationReZip3.BasePointCity { + return p.dtodPlannerMileage.DTODZip5Distance(appCtx, source, destination) + } } return randMcNallyZip3Distance(appCtx, sourceZip3, destZip3) diff --git a/pkg/route/hhg_planner_test.go b/pkg/route/hhg_planner_test.go index a2725ef1c3a..15c4fb03d14 100644 --- a/pkg/route/hhg_planner_test.go +++ b/pkg/route/hhg_planner_test.go @@ -78,7 +78,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false) + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30301", false, false) suite.NoError(err) suite.Equal(149, distance) }) @@ -88,7 +88,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "11201", "11201", false) + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "11201", "11201", false, false) suite.NoError(err) suite.Equal(1, distance) }) @@ -105,7 +105,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { planner := NewHHGPlanner(plannerMileage) // Get distance between two zips in the same base point city - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "33169", "33040", false) + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "33169", "33040", false, false) suite.NoError(err) // Ensure DTOD was used for distance @@ -121,7 +121,7 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) planner := NewHHGPlanner(plannerMileage) - distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901", false) + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "30907", "30901", false, false) suite.Error(err) suite.Equal(0, distance) }) diff --git a/pkg/route/mocks/Planner.go b/pkg/route/mocks/Planner.go index bbbe8cf7787..f6ce16a0e45 100644 --- a/pkg/route/mocks/Planner.go +++ b/pkg/route/mocks/Planner.go @@ -156,9 +156,9 @@ func (_m *Planner) Zip5TransitDistanceLineHaul(appCtx appcontext.AppContext, sou return r0, r1 } -// ZipTransitDistance provides a mock function with given fields: appCtx, source, destination, useDTOD -func (_m *Planner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) { - ret := _m.Called(appCtx, source, destination, useDTOD) +// ZipTransitDistance provides a mock function with given fields: appCtx, source, destination, useDTOD, isInternationalShipment +func (_m *Planner) ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool, isInternationalShipment bool) (int, error) { + ret := _m.Called(appCtx, source, destination, useDTOD, isInternationalShipment) if len(ret) == 0 { panic("no return value specified for ZipTransitDistance") @@ -166,17 +166,17 @@ func (_m *Planner) ZipTransitDistance(appCtx appcontext.AppContext, source strin var r0 int var r1 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string, bool) (int, error)); ok { - return rf(appCtx, source, destination, useDTOD) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string, bool, bool) (int, error)); ok { + return rf(appCtx, source, destination, useDTOD, isInternationalShipment) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string, bool) int); ok { - r0 = rf(appCtx, source, destination, useDTOD) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, string, bool, bool) int); ok { + r0 = rf(appCtx, source, destination, useDTOD, isInternationalShipment) } else { r0 = ret.Get(0).(int) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, string, bool) error); ok { - r1 = rf(appCtx, source, destination, useDTOD) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, string, bool, bool) error); ok { + r1 = rf(appCtx, source, destination, useDTOD, isInternationalShipment) } else { r1 = ret.Error(1) } diff --git a/pkg/route/planner.go b/pkg/route/planner.go index 1b6c808c23f..591dcec643b 100644 --- a/pkg/route/planner.go +++ b/pkg/route/planner.go @@ -120,7 +120,7 @@ type Planner interface { // Zip5TransitDistanceLineHaul is used by PPM flow and checks for minimum distance restriction as PPM doesn't allow short hauls // New code should probably make the minimum checks after calling Zip5TransitDistance over using this method Zip5TransitDistanceLineHaul(appCtx appcontext.AppContext, source string, destination string) (int, error) - ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool) (int, error) + ZipTransitDistance(appCtx appcontext.AppContext, source string, destination string, useDTOD bool, isInternationalShipment bool) (int, error) Zip3TransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) Zip5TransitDistance(appCtx appcontext.AppContext, source string, destination string) (int, error) } diff --git a/pkg/route/planner_test.go b/pkg/route/planner_test.go index cfbd39dd69f..4a0d968c1f9 100644 --- a/pkg/route/planner_test.go +++ b/pkg/route/planner_test.go @@ -109,7 +109,7 @@ func (suite *PlannerFullSuite) TestZipDistance() { {zip1: "902101234", zip2: caZip, distanceMin: 30, distanceMax: 49}, } for _, ts := range tests { - distance, err := suite.planner.ZipTransitDistance(suite.AppContextForTest(), ts.zip1, ts.zip2, false) + distance, err := suite.planner.ZipTransitDistance(suite.AppContextForTest(), ts.zip1, ts.zip2, false, false) if len(ts.zip1) > 5 { suite.Error(err) suite.Equal(distance, 0) diff --git a/pkg/services/move_history/move_history_fetcher_test.go b/pkg/services/move_history/move_history_fetcher_test.go index b3b89e7ed99..9da8d13f3bb 100644 --- a/pkg/services/move_history/move_history_fetcher_test.go +++ b/pkg/services/move_history/move_history_fetcher_test.go @@ -376,6 +376,7 @@ func (suite *MoveHistoryServiceSuite) TestMoveHistoryFetcherScenarios() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) updater := mtoserviceitem.NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) @@ -552,6 +553,7 @@ func (suite *MoveHistoryServiceSuite) TestMoveHistoryFetcherScenarios() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -626,6 +628,7 @@ func (suite *MoveHistoryServiceSuite) TestMoveHistoryFetcherScenarios() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) 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 8af2f105f66..ed4df5b58d5 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 @@ -60,6 +60,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdateStatusSer mock.Anything, mock.Anything, false, + false, ).Return(400, nil) mtoUpdater := mt.NewMoveTaskOrderUpdater( queryBuilder, @@ -348,6 +349,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdatePostCouns mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -516,6 +518,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_ShowHide() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -758,6 +761,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_MakeAvailableTo mock.Anything, mock.Anything, false, + false, ).Return(400, 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) @@ -797,6 +801,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_MakeAvailableTo mock.Anything, mock.Anything, false, + false, ).Return(400, 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) @@ -1047,6 +1052,7 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderUpdater_UpdatePPMType() mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { 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 a92febd28e8..6bac7e4ec89 100644 --- a/pkg/services/mto_service_item/mto_service_item_creator.go +++ b/pkg/services/mto_service_item/mto_service_item_creator.go @@ -128,7 +128,7 @@ func (o *mtoServiceItemCreator) findEstimatedPrice(appCtx appcontext.AppContext, return 0, err } if mtoShipment.PickupAddress != nil && mtoShipment.DestinationAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false, false) if err != nil { return 0, err } @@ -144,7 +144,7 @@ func (o *mtoServiceItemCreator) findEstimatedPrice(appCtx appcontext.AppContext, return 0, err } if mtoShipment.PickupAddress != nil && mtoShipment.DestinationAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false, false) if err != nil { return 0, err } @@ -167,7 +167,7 @@ func (o *mtoServiceItemCreator) findEstimatedPrice(appCtx appcontext.AppContext, } if mtoShipment.PickupAddress != nil && mtoShipment.DestinationAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false, false) if err != nil { return 0, err } @@ -303,14 +303,14 @@ func (o *mtoServiceItemCreator) calculateSITDeliveryMiles(appCtx appcontext.AppC originalSITAddressZip = mtoShipment.PickupAddress.PostalCode } if mtoShipment.PickupAddress != nil && originalSITAddressZip != "" { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, originalSITAddressZip, false) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, originalSITAddressZip, false, false) } } if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || serviceItem.ReService.Code == models.ReServiceCodeDDASIT || serviceItem.ReService.Code == models.ReServiceCodeDDSFSC || serviceItem.ReService.Code == models.ReServiceCodeDDDSIT { // Creation: Destination SIT: distance between shipment destination address & service item destination address if mtoShipment.DestinationAddress != nil && serviceItem.SITDestinationFinalAddress != nil { - distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationFinalAddress.PostalCode, false) + distance, err = o.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationFinalAddress.PostalCode, false, false) } } if err != nil { 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 619be14b026..d2a7709b9ff 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 @@ -194,6 +194,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateMTOServiceItemWithInvalidMove mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) serviceItemForUnapprovedMove := suite.buildValidServiceItemWithInvalidMove() @@ -223,6 +224,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateMTOServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1034,6 +1036,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1084,6 +1087,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1159,6 +1163,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1286,6 +1291,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1321,6 +1327,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1355,6 +1362,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1431,6 +1439,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateOriginSITServiceItemFailToCre mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1466,6 +1475,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateDestSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -1766,6 +1776,7 @@ func (suite *MTOServiceItemServiceSuite) TestCreateDestSITServiceItem() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) createdServiceItems, _, err := creator.CreateMTOServiceItem(suite.AppContextForTest(), &serviceItemDDASIT) 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 5cf23590cd7..544d1374ecd 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -244,7 +244,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, if serviceItem.ReService.Code == models.ReServiceCodeDDDSIT || serviceItem.ReService.Code == models.ReServiceCodeDDSFSC { // Destination SIT: distance between shipment destination address & service item ORIGINAL destination address - milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) + milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false, false) if err != nil { return nil, err } @@ -256,7 +256,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, if serviceItem.ReService.Code == models.ReServiceCodeDOPSIT || serviceItem.ReService.Code == models.ReServiceCodeDOSFSC { // Origin SIT: distance between shipment pickup address & service item ORIGINAL pickup address - milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false) + milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false, false) if err != nil { return nil, err } @@ -384,7 +384,7 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItemPrime( func calculateOriginSITRequiredDeliveryDate(appCtx appcontext.AppContext, shipment models.MTOShipment, planner route.Planner, sitCustomerContacted *time.Time, sitDepartureDate *time.Time) (*time.Time, error) { // Get a distance calculation between pickup and destination addresses. - distance, err := planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, false) + distance, err := planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, false, false) if err != nil { return nil, apperror.NewUnprocessableEntityError("cannot calculate distance between pickup and destination addresses") 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 d33bf218ab1..c41540db364 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 @@ -50,6 +50,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) updater := NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -328,6 +329,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -453,6 +455,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -582,6 +585,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -709,6 +713,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -786,6 +791,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -857,6 +863,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -966,6 +973,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1082,6 +1090,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1243,6 +1252,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1354,6 +1364,7 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1234, apperror.UnprocessableEntityError{}) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1971,6 +1982,7 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) updater := NewMTOServiceItemUpdater(planner, builder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) diff --git a/pkg/services/mto_shipment/mto_shipment_address_updater.go b/pkg/services/mto_shipment/mto_shipment_address_updater.go index 4b6efc1d478..b000991dea4 100644 --- a/pkg/services/mto_shipment/mto_shipment_address_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_address_updater.go @@ -72,9 +72,9 @@ func UpdateOriginSITServiceItemSITDeliveryMiles(planner route.Planner, shipment // Origin SIT: distance between shipment pickup address & service item ORIGINAL pickup address if serviceItem.SITOriginHHGOriginalAddress != nil { - milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false) + milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false, false) } else { - milesCalculated, err = planner.ZipTransitDistance(appCtx, oldAddress.PostalCode, newAddress.PostalCode, false) + milesCalculated, err = planner.ZipTransitDistance(appCtx, oldAddress.PostalCode, newAddress.PostalCode, false, false) } if err != nil { return nil, err diff --git a/pkg/services/mto_shipment/mto_shipment_address_updater_test.go b/pkg/services/mto_shipment/mto_shipment_address_updater_test.go index 2e81afcecfb..da9621dd279 100644 --- a/pkg/services/mto_shipment/mto_shipment_address_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_address_updater_test.go @@ -20,6 +20,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateMTOShipmentAddress() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) addressCreator := address.NewAddressCreator() addressUpdater := address.NewAddressUpdater() @@ -171,6 +172,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateMTOShipmentAddress() { mock.Anything, mock.Anything, false, + false, ).Return(465, nil) mtoServiceItems, _ := UpdateOriginSITServiceItemSITDeliveryMiles(planner, &externalShipment, &newAddress, &oldAddress, suite.AppContextForTest()) suite.Equal(2, len(*mtoServiceItems)) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 8670720cbd2..090531c9f3b 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -860,16 +860,34 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, newShipment.DestinationAddress != nil && newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || newShipment.RequestedPickupDate != nil && newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { - // the db proc consumes the mileage needed, so we need to get that first - mileage, err := f.planner.ZipTransitDistance(appCtx, newShipment.PickupAddress.PostalCode, newShipment.DestinationAddress.PostalCode, true) + portZip, portType, err := models.GetPortLocationInfoForShipment(appCtx.DB(), newShipment.ID) if err != nil { return err } + // if we don't have the port data, then we won't worry about pricing + if portZip != nil && portType != nil { + var pickupZip string + var destZip string + // if the port type is POEFSC this means the shipment is CONUS -> OCONUS (pickup -> port) + // if the port type is PODFSC this means the shipment is OCONUS -> CONUS (port -> destination) + if *portType == models.ReServiceCodePOEFSC.String() { + pickupZip = newShipment.PickupAddress.PostalCode + destZip = *portZip + } else if *portType == models.ReServiceCodePODFSC.String() { + pickupZip = *portZip + destZip = newShipment.DestinationAddress.PostalCode + } + // we need to get the mileage from DTOD first, the db proc will consume that + mileage, err := f.planner.ZipTransitDistance(appCtx, pickupZip, destZip, true, true) + if err != nil { + return err + } - // Update the service item pricing if relevant fields have changed - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment, mileage) - if err != nil { - return err + // update the service item pricing if relevant fields have changed + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment, mileage) + if err != nil { + return err + } } } @@ -1180,7 +1198,7 @@ func CalculateRequiredDeliveryDate(appCtx appcontext.AppContext, planner route.P "99950", "99824", "99850", "99901", "99928", "99950", "99835"} // Get a distance calculation between pickup and destination addresses. - distance, err := planner.ZipTransitDistance(appCtx, pickupAddress.PostalCode, destinationAddress.PostalCode, false) + distance, err := planner.ZipTransitDistance(appCtx, pickupAddress.PostalCode, destinationAddress.PostalCode, false, false) if err != nil { return nil, err } @@ -1331,11 +1349,11 @@ func UpdateDestinationSITServiceItemsSITDeliveryMiles(planner route.Planner, app if TOOApprovalRequired { if serviceItem.SITDestinationOriginalAddress != nil { // if TOO approval was required, shipment destination address has been updated at this point - milesCalculated, err = planner.ZipTransitDistance(appCtx, shipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) + milesCalculated, err = planner.ZipTransitDistance(appCtx, shipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false, false) } } else { // if TOO approval was not required, use the newAddress - milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) + milesCalculated, err = planner.ZipTransitDistance(appCtx, newAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false, false) } if err != nil { return err diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index cc11aa6678c..05ea51d229d 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -51,6 +51,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { mock.Anything, mock.Anything, false, + false, ).Return(1000, nil) moveRouter := moveservices.NewMoveRouter() moveWeights := moveservices.NewMoveWeights(NewShipmentReweighRequester()) @@ -465,6 +466,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { "50314", "99505", true, + false, ).Return(1000, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ @@ -1989,6 +1991,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateMTOShipmentStatus() { mock.AnythingOfType("string"), mock.AnythingOfType("string"), false, + false, ).Return(500, nil).Run(func(args mock.Arguments) { TransitDistancePickupArg = args.Get(1).(string) TransitDistanceDestinationArg = args.Get(2).(string) @@ -3144,6 +3147,7 @@ func (suite *MTOShipmentServiceSuite) TestUpdateStatusServiceItems() { mock.Anything, mock.Anything, false, + false, ).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) diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index eadc0229aa1..396f94a12e9 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -88,14 +88,34 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen // Update the service item pricing if we have the estimated weight if shipment.PrimeEstimatedWeight != nil { - mileage, err := f.planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, true) + portZip, portType, err := models.GetPortLocationInfoForShipment(appCtx.DB(), shipment.ID) if err != nil { return err } + // if we don't have the port data, then we won't worry about pricing + if portZip != nil && portType != nil { + var pickupZip string + var destZip string + // if the port type is POEFSC this means the shipment is CONUS -> OCONUS (pickup -> port) + // if the port type is PODFSC this means the shipment is OCONUS -> CONUS (port -> destination) + if *portType == models.ReServiceCodePOEFSC.String() { + pickupZip = shipment.PickupAddress.PostalCode + destZip = *portZip + } else if *portType == models.ReServiceCodePODFSC.String() { + pickupZip = *portZip + destZip = shipment.DestinationAddress.PostalCode + } + // we need to get the mileage from DTOD first, the db proc will consume that + mileage, err := f.planner.ZipTransitDistance(appCtx, pickupZip, destZip, true, true) + if err != nil { + return err + } - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment, mileage) - if err != nil { - return err + // update the service item pricing if relevant fields have changed + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment, mileage) + if err != nil { + return err + } } } } else { diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 109d0822eec..3b4f0f9c078 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -91,6 +91,7 @@ func (suite *MTOShipmentServiceSuite) createApproveShipmentSubtestData() (subtes mock.Anything, mock.Anything, false, + false, ).Return(400, nil) siCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) subtestData.planner = &mocks.Planner{} @@ -278,12 +279,14 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.Anything, mock.Anything, false, + false, ).Return(500, nil) planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50314", "99505", true, + false, ).Return(1000, nil) // Approve international shipment @@ -345,6 +348,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.Anything, mock.Anything, false, + false, ).Return(500, nil) preApprovalTime := time.Now() @@ -465,6 +469,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { createdShipment.PickupAddress.PostalCode, createdShipment.DestinationAddress.PostalCode, false, + false, ).Return(500, nil) shipmentHeavyEtag := etag.GenerateEtag(shipmentHeavy.UpdatedAt) @@ -741,6 +746,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("string"), mock.AnythingOfType("string"), false, + false, ).Return(500, nil).Run(func(args mock.Arguments) { TransitDistancePickupArg = args.Get(1).(string) TransitDistanceDestinationArg = args.Get(2).(string) @@ -796,6 +802,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("string"), mock.AnythingOfType("string"), false, + false, ).Return(500, nil) suite.Equal(8000, *shipment.MoveTaskOrder.Orders.Entitlement.AuthorizedWeight()) @@ -837,6 +844,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.AnythingOfType("string"), mock.AnythingOfType("string"), false, + false, ).Return(500, nil) shipmentEtag := etag.GenerateEtag(shipment.UpdatedAt) diff --git a/pkg/services/mto_shipment/shipment_deleter_test.go b/pkg/services/mto_shipment/shipment_deleter_test.go index 6a0d900c128..35c86bc68ac 100644 --- a/pkg/services/mto_shipment/shipment_deleter_test.go +++ b/pkg/services/mto_shipment/shipment_deleter_test.go @@ -30,6 +30,7 @@ func (suite *MTOShipmentServiceSuite) TestShipmentDeleter() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { @@ -261,6 +262,7 @@ func (suite *MTOShipmentServiceSuite) TestPrimeShipmentDeleter() { mock.Anything, mock.Anything, false, + false, ).Return(400, nil) setUpSignedCertificationCreatorMock := func(returnValue ...interface{}) services.SignedCertificationCreator { diff --git a/pkg/services/payment_request/payment_request_creator_test.go b/pkg/services/payment_request/payment_request_creator_test.go index 17aca04b33b..cc8d50d01d2 100644 --- a/pkg/services/payment_request/payment_request_creator_test.go +++ b/pkg/services/payment_request/payment_request_creator_test.go @@ -328,6 +328,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequest() { mock.Anything, mock.Anything, false, + false, ).Return(0, nil) }) @@ -570,6 +571,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequest() { mock.Anything, mock.Anything, false, + false, ).Return(0, nil) failingCreator := NewPaymentRequestCreator(planner, failingServiceItemPricer) @@ -1462,6 +1464,7 @@ func (suite *PaymentRequestServiceSuite) TestCreatePaymentRequestCheckOnNTSRelea testStorageFacilityZip, testDestinationZip, false, + false, ).Return(testZip3Distance, nil) // Create an initial payment request. diff --git a/pkg/services/payment_request/payment_request_recalculator_test.go b/pkg/services/payment_request/payment_request_recalculator_test.go index 94b21d42e71..7d5120dcd55 100644 --- a/pkg/services/payment_request/payment_request_recalculator_test.go +++ b/pkg/services/payment_request/payment_request_recalculator_test.go @@ -56,6 +56,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() recalculateTestPickupZip, recalculateTestDestinationZip, false, + false, ).Return(recalculateTestZip3Distance, nil) // Create an initial payment request. @@ -297,6 +298,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestErrors() { recalculateTestPickupZip, recalculateTestDestinationZip, false, + false, ).Return(recalculateTestZip3Distance, nil) // Create an initial payment request. diff --git a/pkg/services/payment_request/payment_request_shipment_recalculate_test.go b/pkg/services/payment_request/payment_request_shipment_recalculate_test.go index d308e237efb..d32beaa61b7 100644 --- a/pkg/services/payment_request/payment_request_shipment_recalculate_test.go +++ b/pkg/services/payment_request/payment_request_shipment_recalculate_test.go @@ -28,6 +28,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculateShipmentPaymentRequestSu recalculateTestPickupZip, recalculateTestDestinationZip, false, + false, ).Return(recalculateTestZip3Distance, nil) // Create an initial payment request. @@ -138,6 +139,7 @@ func (suite *PaymentRequestServiceSuite) TestRecalculateShipmentPaymentRequestEr recalculateTestPickupZip, recalculateTestDestinationZip, false, + false, ).Return(recalculateTestZip3Distance, nil) creator := NewPaymentRequestCreator(mockPlanner, ghcrateengine.NewServiceItemPricer()) diff --git a/pkg/services/ppm_closeout/ppm_closeout_test.go b/pkg/services/ppm_closeout/ppm_closeout_test.go index ac86dee3f04..c1479c140ea 100644 --- a/pkg/services/ppm_closeout/ppm_closeout_test.go +++ b/pkg/services/ppm_closeout/ppm_closeout_test.go @@ -337,7 +337,7 @@ func (suite *PPMCloseoutSuite) TestPPMShipmentCreator() { appCtx := suite.AppContextForTest() mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) mockedPaymentRequestHelper.On( "FetchServiceParamsForServiceItems", @@ -393,7 +393,7 @@ func (suite *PPMCloseoutSuite) TestPPMShipmentCreator() { appCtx := suite.AppContextForTest() mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) mockedPaymentRequestHelper.On( "FetchServiceParamsForServiceItems", diff --git a/pkg/services/ppmshipment/ppm_estimator_test.go b/pkg/services/ppmshipment/ppm_estimator_test.go index d4ca213d2ac..71b0749a7ea 100644 --- a/pkg/services/ppmshipment/ppm_estimator_test.go +++ b/pkg/services/ppmshipment/ppm_estimator_test.go @@ -492,13 +492,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) linehaul, fuel, origin, dest, packing, unpacking, _, err := ppmEstimator.PriceBreakdown(suite.AppContextForTest(), &ppmShipment) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(unit.Pound(4000), *ppmShipment.EstimatedWeight) @@ -537,13 +537,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -574,13 +574,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -608,13 +608,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -642,13 +642,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.PickupAddress.PostalCode, newPPM.PickupAddress.PostalCode) @@ -678,7 +678,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil).Once() + "50309", "30813", false, false).Return(2294, nil).Once() ppmEstimate, _, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) @@ -764,13 +764,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { mock.AnythingOfType("[]models.MTOServiceItem")).Return(serviceParams, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) maxIncentive, err := ppmEstimator.MaxIncentive(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(unit.Cents(128398858), *maxIncentive) @@ -825,13 +825,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -876,12 +876,12 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { mock.AnythingOfType("[]models.MTOServiceItem")).Return(serviceParams, nil) // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles - mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false).Return(2294, nil) + mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false, false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) - mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false) + mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -927,12 +927,12 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmFinalIncentiveLimitedByAllowableWeight, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) - mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false) + mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -982,13 +982,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) suite.Equal(oldPPMShipment.ActualPickupPostalCode, newPPM.ActualPickupPostalCode) @@ -1039,13 +1039,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) @@ -1101,13 +1101,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) @@ -1171,13 +1171,13 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { // DTOD distance is going to be less than the HHG Rand McNally distance of 2361 miles mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) ppmFinal, err := ppmEstimator.FinalIncentiveWithDefaultChecks(suite.AppContextForTest(), oldPPMShipment, &newPPM) suite.NilOrNoVerrs(err) mockedPlanner.AssertCalled(suite.T(), "ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false) + "50309", "30813", false, false) mockedPaymentRequestHelper.AssertCalled(suite.T(), "FetchServiceParamsForServiceItems", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("[]models.MTOServiceItem")) originalWeight, newWeight := SumWeightTickets(oldPPMShipment, newPPM) @@ -1666,7 +1666,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { }, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) _, estimatedSITCost, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), models.PPMShipment{}, &shipmentOriginSIT) @@ -1728,7 +1728,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { }, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) _, estimatedSITCost, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), models.PPMShipment{}, &shipmentDestinationSIT) @@ -1790,7 +1790,7 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { }, }, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30813", false).Return(2294, nil) + "50309", "30813", false, false).Return(2294, nil) _, estimatedSITCost, err := ppmEstimator.EstimateIncentiveWithDefaultChecks(suite.AppContextForTest(), models.PPMShipment{}, &shipmentOriginSIT) @@ -1980,10 +1980,10 @@ func (suite *PPMShipmentSuite) TestPPMEstimator() { shipmentDifferentDeparture.ExpectedDepartureDate = originalShipment.ExpectedDepartureDate.Add(time.Hour * 24 * 70) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90211", "30813", false).Return(2294, nil) + "90211", "30813", false, false).Return(2294, nil) mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50309", "30814", false).Return(2290, nil) + "50309", "30814", false, false).Return(2290, nil) // SIT specific field changes will likely cause the price to change, although adjusting dates may not change // the total number of days in SIT. diff --git a/pkg/services/ppmshipment/ppm_shipment_updater_test.go b/pkg/services/ppmshipment/ppm_shipment_updater_test.go index 3ee017878b4..607491af64c 100644 --- a/pkg/services/ppmshipment/ppm_shipment_updater_test.go +++ b/pkg/services/ppmshipment/ppm_shipment_updater_test.go @@ -1504,7 +1504,7 @@ func (suite *PPMShipmentSuite) TestUpdatePPMShipment() { originalPPM.DestinationAddress = destinationAddress mockedPlanner := &routemocks.Planner{} mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813", false).Return(2294, nil) + "90210", "30813", false, false).Return(2294, nil) updatedPPM, err := subtestData.ppmShipmentUpdater.UpdatePPMShipmentSITEstimatedCost(appCtx, &originalPPM) @@ -1560,7 +1560,7 @@ func (suite *PPMShipmentSuite) TestUpdatePPMShipment() { originalPPM.DestinationAddress = destinationAddress mockedPlanner := &routemocks.Planner{} mockedPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813", false).Return(2294, nil) + "90210", "30813", false, false).Return(2294, nil) updatedPPM, err := subtestData.ppmShipmentUpdater.UpdatePPMShipmentSITEstimatedCost(appCtx, &originalPPM) diff --git a/pkg/services/reweigh/reweigh_updater_test.go b/pkg/services/reweigh/reweigh_updater_test.go index c1501906a98..77805ecf4ac 100644 --- a/pkg/services/reweigh/reweigh_updater_test.go +++ b/pkg/services/reweigh/reweigh_updater_test.go @@ -32,6 +32,7 @@ func (suite *ReweighSuite) TestReweighUpdater() { recalculateTestPickupZip, recalculateTestDestinationZip, false, + false, ).Return(recalculateTestZip3Distance, nil) // Get shipment payment request recalculator service diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index 3c33ac47115..d43dced8a8d 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -41,7 +41,7 @@ func NewShipmentAddressUpdateRequester(planner route.Planner, addressCreator ser func (f *shipmentAddressUpdateRequester) isAddressChangeDistanceOver50(appCtx appcontext.AppContext, addressUpdate models.ShipmentAddressUpdate) (bool, error) { //We calculate and set the distance between the old and new address - distance, err := f.planner.ZipTransitDistance(appCtx, addressUpdate.OriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode, false) + distance, err := f.planner.ZipTransitDistance(appCtx, addressUpdate.OriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode, false, false) if err != nil { return false, err } @@ -92,11 +92,11 @@ func (f *shipmentAddressUpdateRequester) doesDeliveryAddressUpdateChangeMileageB return false, nil } - previousDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, originalDeliveryAddress.PostalCode, false) + previousDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, originalDeliveryAddress.PostalCode, false, false) if err != nil { return false, err } - newDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, newDeliveryAddress.PostalCode, false) + newDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, newDeliveryAddress.PostalCode, false, false) if err != nil { return false, err } @@ -308,14 +308,14 @@ func (f *shipmentAddressUpdateRequester) RequestShipmentDeliveryAddressUpdate(ap if addressUpdate.NewSitDistanceBetween != nil { distanceBetweenOld = *addressUpdate.NewSitDistanceBetween } else { - distanceBetweenOld, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.OriginalAddress.PostalCode, false) + distanceBetweenOld, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.OriginalAddress.PostalCode, false, false) } if err != nil { return nil, err } // calculating distance between the new address update & the SIT - distanceBetweenNew, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode, false) + distanceBetweenNew, err = f.planner.ZipTransitDistance(appCtx, addressUpdate.SitOriginalAddress.PostalCode, addressUpdate.NewAddress.PostalCode, false, false) if err != nil { return nil, err } @@ -607,14 +607,34 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc if shipment.PrimeEstimatedWeight != nil && shipment.MarketCode == models.MarketCodeInternational && tooApprovalStatus == models.ShipmentAddressUpdateStatusApproved { - // the db proc consumes the mileage needed, so we need to get that first - mileage, err := f.planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, true) + portZip, portType, err := models.GetPortLocationInfoForShipment(appCtx.DB(), shipment.ID) if err != nil { return err } - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, mileage) - if err != nil { - return err + // if we don't have the port data, then we won't worry about pricing + if portZip != nil && portType != nil { + var pickupZip string + var destZip string + // if the port type is POEFSC this means the shipment is CONUS -> OCONUS (pickup -> port) + // if the port type is PODFSC this means the shipment is OCONUS -> CONUS (port -> destination) + if *portType == models.ReServiceCodePOEFSC.String() { + pickupZip = shipment.PickupAddress.PostalCode + destZip = *portZip + } else if *portType == models.ReServiceCodePODFSC.String() { + pickupZip = *portZip + destZip = shipment.DestinationAddress.PostalCode + } + // we need to get the mileage from DTOD first, the db proc will consume that + mileage, err := f.planner.ZipTransitDistance(appCtx, pickupZip, destZip, true, true) + if err != nil { + return err + } + + // update the service item pricing if relevant fields have changed + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, mileage) + if err != nil { + return err + } } } diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index 64d2c0fd46d..d8af5b02950 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -72,12 +72,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres "90210", "94535", false, + false, ).Return(2500, nil).Twice() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false, + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), nil, nil) @@ -129,6 +131,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("string"), mock.AnythingOfType("string"), false, + false, ).Return(0, fmt.Errorf("error calculating distance 2")).Once() testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ @@ -269,12 +272,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres "90210", "94535", false, + false, ).Return(2500, nil).Times(4) mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false, + false, ).Return(2500, nil).Twice() update, err := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) @@ -301,12 +306,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres "89523", "89503", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", false, + false, ).Return(2500, nil).Once() newAddress := models.Address{ StreetAddress1: "123 Any St", @@ -348,12 +355,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres "89523", "89503", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", false, + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -395,12 +404,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres "90210", "94535", false, + false, ).Return(0, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "89503", false, + false, ).Return(200, nil).Once() testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ @@ -524,12 +535,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres mock.AnythingOfType("string"), "87108", false, + false, ).Return(500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.AnythingOfType("string"), "87053", false, + false, ).Return(501, nil).Once() suite.NotEmpty(move.MTOShipments) update, err := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) @@ -584,18 +597,21 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres "94535", "94535", false, + false, ).Return(0, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94523", "90210", false, + false, ).Return(500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "90210", false, + false, ).Return(501, nil).Once() // request the update @@ -622,6 +638,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.Anything, mock.Anything, false, + false, ).Return(400, nil) addressUpdateRequester := NewShipmentAddressUpdateRequester(mockPlanner, addressCreator, moveRouter) @@ -996,6 +1013,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.Anything, mock.Anything, false, + false, ).Return(300, nil) mockPlanner.On("ZipTransitDistance", @@ -1003,6 +1021,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.Anything, mock.Anything, true, + false, ).Return(300, nil) newDestUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99703") @@ -1116,12 +1135,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp "89523", "89503", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", false, + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -1184,12 +1205,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp "89523", "89503", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", false, + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -1264,12 +1287,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp "90210", "94535", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false, + false, ).Return(2500, nil).Once() addressChange, _ := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) @@ -1292,12 +1317,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp "89523", "89503", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", false, + false, ).Return(2500, nil).Once() move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ @@ -1355,12 +1382,14 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp "89523", "89503", false, + false, ).Return(2500, nil).Once() mockPlanner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "89523", "90210", false, + false, ).Return(2500, nil).Once() newAddress := models.Address{ StreetAddress1: "123 Any St", @@ -1417,6 +1446,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp "94535", "94535", false, + false, ).Return(30, nil) move := setupTestData() shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), nil, nil) diff --git a/pkg/services/sit_extension/sit_extension_denier.go b/pkg/services/sit_extension/sit_extension_denier.go index 07cd9477c16..cc8fc66d2a8 100644 --- a/pkg/services/sit_extension/sit_extension_denier.go +++ b/pkg/services/sit_extension/sit_extension_denier.go @@ -34,6 +34,7 @@ func NewSITExtensionDenier(moveRouter services.MoveRouter) services.SITExtension mock.Anything, mock.Anything, false, + false, ).Return(400, nil) return &sitExtensionDenier{moveRouter, mtoserviceitem.NewMTOServiceItemUpdater(planner, query.NewQueryBuilder(), moveRouter, mtoshipment.NewMTOShipmentFetcher(), address.NewAddressCreator(), portlocation.NewPortLocationFetcher())} } diff --git a/pkg/testdatagen/scenario/shared.go b/pkg/testdatagen/scenario/shared.go index dfe99dbda5b..d5425b5cef3 100644 --- a/pkg/testdatagen/scenario/shared.go +++ b/pkg/testdatagen/scenario/shared.go @@ -4212,6 +4212,7 @@ func createHHGWithOriginSITServiceItems( mock.Anything, mock.Anything, false, + false, ).Return(400, nil) queryBuilder := query.NewQueryBuilder() @@ -4239,7 +4240,7 @@ func createHHGWithOriginSITServiceItems( // called for zip 3 domestic linehaul service item planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813", false).Return(2361, nil) + "90210", "30813", false, false).Return(2361, nil) shipmentUpdater := mtoshipment.NewMTOShipmentStatusUpdater(queryBuilder, serviceItemCreator, planner) _, updateErr := shipmentUpdater.UpdateMTOShipmentStatus(appCtx, shipment.ID, models.MTOShipmentStatusApproved, nil, nil, etag.GenerateEtag(shipment.UpdatedAt)) @@ -4291,6 +4292,7 @@ func createHHGWithOriginSITServiceItems( mock.Anything, mock.Anything, false, + false, ).Return(400, nil) serviceItemUpdator := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -4483,6 +4485,7 @@ func createHHGWithDestinationSITServiceItems(appCtx appcontext.AppContext, prime mock.Anything, mock.Anything, false, + false, ).Return(400, nil) serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -4510,7 +4513,7 @@ func createHHGWithDestinationSITServiceItems(appCtx appcontext.AppContext, prime // called for zip 3 domestic linehaul service item planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "90210", "30813", false).Return(2361, nil) + "90210", "30813", false, false).Return(2361, nil) shipmentUpdater := mtoshipment.NewMTOShipmentStatusUpdater(queryBuilder, serviceItemCreator, planner) _, updateErr := shipmentUpdater.UpdateMTOShipmentStatus(appCtx, shipment.ID, models.MTOShipmentStatusApproved, nil, nil, etag.GenerateEtag(shipment.UpdatedAt)) @@ -4557,6 +4560,7 @@ func createHHGWithDestinationSITServiceItems(appCtx appcontext.AppContext, prime mock.Anything, mock.Anything, false, + false, ).Return(400, nil) serviceItemUpdator := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -4893,7 +4897,7 @@ func createHHGWithPaymentServiceItems( queryBuilder := query.NewQueryBuilder() planner := &routemocks.Planner{} - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(123, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false, false).Return(123, nil).Once() serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -4918,33 +4922,33 @@ func createHHGWithPaymentServiceItems( logger.Fatal("Error approving move") } // called using the addresses with origin zip of 90210 and destination zip of 94535 - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(348, nil).Times(2) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false, false).Return(348, nil).Times(2) // called using the addresses with origin zip of 90210 and destination zip of 90211 - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(3, nil).Times(5) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false, false).Return(3, nil).Times(5) // called for zip 3 domestic linehaul service item planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false).Return(348, nil).Times(2) // called for zip 5 domestic linehaul service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false).Return(348, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false, false).Return(348, nil).Once() // called for domestic shorthaul service item planner.On("Zip5TransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "90211").Return(3, nil).Times(7) // called for domestic shorthaul service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "90211", false).Return(348, nil).Times(10) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "90211", false, false).Return(348, nil).Times(10) // called for domestic origin SIT pickup service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", false).Return(348, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "90210", "94535", false, false).Return(348, nil).Once() // called for domestic destination SIT delivery service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "90210", false).Return(348, nil).Times(2) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "90210", false, false).Return(348, nil).Times(2) // called for DLH, DSH, FSC service item estimated price calculations - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(400, nil).Times(3) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false, false).Return(400, nil).Times(3) for _, shipment := range []models.MTOShipment{longhaulShipment, shorthaulShipment, shipmentWithOriginalWeight, shipmentWithOriginalAndReweighWeight, shipmentWithOriginalAndReweighWeightReweihBolded, shipmentWithOriginalReweighAndAdjustedWeight, shipmentWithOriginalAndAdjustedWeight} { shipmentUpdater := mtoshipment.NewMTOShipmentStatusUpdater(queryBuilder, serviceItemCreator, planner) @@ -5040,6 +5044,7 @@ func createHHGWithPaymentServiceItems( mock.Anything, mock.Anything, false, + false, ).Return(400, nil) serviceItemUpdater := mtoserviceitem.NewMTOServiceItemUpdater(planner, queryBuilder, moveRouter, shipmentFetcher, addressCreator, portLocationFetcher) @@ -5528,6 +5533,7 @@ func createHHGMoveWithPaymentRequest(appCtx appcontext.AppContext, userUploader mock.Anything, mock.Anything, false, + false, ).Return(910, nil) paymentRequestCreator := paymentrequest.NewPaymentRequestCreator( diff --git a/pkg/testdatagen/testharness/make_move.go b/pkg/testdatagen/testharness/make_move.go index 4cc88a4dc24..ddd96329c38 100644 --- a/pkg/testdatagen/testharness/make_move.go +++ b/pkg/testdatagen/testharness/make_move.go @@ -3823,7 +3823,7 @@ func MakeHHGMoveWithApprovedNTSShipmentsForTOO(appCtx appcontext.AppContext) mod planner := &routemocks.Planner{} // mock any and all planner calls - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(2361, nil) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false, false).Return(2361, nil) queryBuilder := query.NewQueryBuilder() serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) @@ -3927,7 +3927,7 @@ func MakeHHGMoveWithApprovedNTSRShipmentsForTOO(appCtx appcontext.AppContext) mo planner := &routemocks.Planner{} // mock any and all planner calls - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false).Return(2361, nil) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), mock.Anything, mock.Anything, false, false).Return(2361, nil) queryBuilder := query.NewQueryBuilder() serviceItemCreator := mtoserviceitem.NewMTOServiceItemCreator(planner, queryBuilder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) From 55bfa543c2e824a6ba2e4f07442fc224688558a1 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 22:36:31 +0000 Subject: [PATCH 23/52] fixing devseed, adjusting migration, and adding in intl shipment check --- ...de_function_and_update_pricing_proc.up.sql | 50 +++++++++---------- pkg/models/mto_shipments.go | 3 +- .../mto_shipment/mto_shipment_updater.go | 7 +-- pkg/services/mto_shipment/rules.go | 2 +- .../mto_shipment/shipment_approver.go | 2 +- pkg/testdatagen/scenario/shared.go | 2 +- 6 files changed, 34 insertions(+), 32 deletions(-) diff --git a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql index a6fd4534b5e..de355bc8146 100644 --- a/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql +++ b/migrations/app/schema/20241216190428_update_get_zip_code_function_and_update_pricing_proc.up.sql @@ -93,6 +93,31 @@ BEGIN END; $$ LANGUAGE plpgsql; +-- this function will help us get the ZIP code & port type for a port to calculate mileage +CREATE OR REPLACE FUNCTION get_port_location_info_for_shipment(shipment_id UUID) +RETURNS TABLE(uspr_zip_id TEXT, port_type TEXT) AS $$ +BEGIN + -- select the ZIP code and port type (POEFSC or PODFSC) + RETURN QUERY + SELECT + COALESCE(poe_usprc.uspr_zip_id::TEXT, pod_usprc.uspr_zip_id::TEXT) AS uspr_zip_id, + CASE + WHEN msi.poe_location_id IS NOT NULL THEN 'POEFSC' + WHEN msi.pod_location_id IS NOT NULL THEN 'PODFSC' + ELSE NULL + END AS port_type + FROM mto_shipments ms + JOIN mto_service_items msi ON ms.id = msi.mto_shipment_id + LEFT JOIN port_locations poe_pl ON msi.poe_location_id = poe_pl.id + LEFT JOIN port_locations pod_pl ON msi.pod_location_id = pod_pl.id + LEFT JOIN us_post_region_cities poe_usprc ON poe_pl.us_post_region_cities_id = poe_usprc.id + LEFT JOIN us_post_region_cities pod_usprc ON pod_pl.us_post_region_cities_id = pod_usprc.id + WHERE ms.id = shipment_id + AND (msi.poe_location_id IS NOT NULL OR msi.pod_location_id IS NOT NULL) + LIMIT 1; +END; +$$ LANGUAGE plpgsql; + -- updating the pricing proc to now consume the mileage we get from DTOD instead of calculate it using Rand McNally -- this is a requirement for E-06210 -- also updating the get_rate_area parameters and passing in the contract_id @@ -207,28 +232,3 @@ BEGIN END; ' LANGUAGE plpgsql; - --- this function will help us get the ZIP code & port type for a port to calculate mileage -CREATE OR REPLACE FUNCTION get_port_location_info_for_shipment(shipment_id UUID) -RETURNS TABLE(uspr_zip_id TEXT, port_type TEXT) AS $$ -BEGIN - -- select the ZIP code and port type (POEFSC or PODFSC) - RETURN QUERY - SELECT - COALESCE(poe_usprc.uspr_zip_id::TEXT, pod_usprc.uspr_zip_id::TEXT) AS uspr_zip_id, - CASE - WHEN msi.poe_location_id IS NOT NULL THEN 'POEFSC' - WHEN msi.pod_location_id IS NOT NULL THEN 'PODFSC' - ELSE NULL - END AS port_type - FROM mto_shipments ms - JOIN mto_service_items msi ON ms.id = msi.mto_shipment_id - LEFT JOIN port_locations poe_pl ON msi.poe_location_id = poe_pl.id - LEFT JOIN port_locations pod_pl ON msi.pod_location_id = pod_pl.id - LEFT JOIN us_post_region_cities poe_usprc ON poe_pl.us_post_region_cities_id = poe_usprc.id - LEFT JOIN us_post_region_cities pod_usprc ON pod_pl.us_post_region_cities_id = pod_usprc.id - WHERE ms.id = shipment_id - AND (msi.poe_location_id IS NOT NULL OR msi.pod_location_id IS NOT NULL) - LIMIT 1; -END; -$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index f832d3f4563..002959be9cc 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -1,6 +1,7 @@ package models import ( + "database/sql" "fmt" "time" @@ -375,7 +376,7 @@ func GetPortLocationInfoForShipment(db *pop.Connection, shipmentID uuid.UUID) (* err := db.RawQuery("SELECT * FROM get_port_location_info_for_shipment($1)", shipmentID). First(&portLocationInfo) - if err != nil { + if err != nil && err != sql.ErrNoRows { return nil, nil, fmt.Errorf("error fetching port location for shipment ID: %s with error %w", shipmentID, err) } diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 090531c9f3b..acb2aec3c23 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -1068,7 +1068,7 @@ func (o *mtoShipmentStatusUpdater) setRequiredDeliveryDate(appCtx appcontext.App pickupLocation = shipment.PickupAddress deliveryLocation = shipment.DestinationAddress } - requiredDeliveryDate, calcErr := CalculateRequiredDeliveryDate(appCtx, o.planner, *pickupLocation, *deliveryLocation, *shipment.ScheduledPickupDate, weight.Int()) + requiredDeliveryDate, calcErr := CalculateRequiredDeliveryDate(appCtx, o.planner, *pickupLocation, *deliveryLocation, *shipment.ScheduledPickupDate, weight.Int(), shipment.MarketCode) if calcErr != nil { return calcErr } @@ -1185,7 +1185,7 @@ func reServiceCodesForShipment(shipment models.MTOShipment) []models.ReServiceCo // CalculateRequiredDeliveryDate function is used to get a distance calculation using the pickup and destination addresses. It then uses // the value returned to make a fetch on the ghc_domestic_transit_times table and returns a required delivery date // based on the max_days_transit_time. -func CalculateRequiredDeliveryDate(appCtx appcontext.AppContext, planner route.Planner, pickupAddress models.Address, destinationAddress models.Address, pickupDate time.Time, weight int) (*time.Time, error) { +func CalculateRequiredDeliveryDate(appCtx appcontext.AppContext, planner route.Planner, pickupAddress models.Address, destinationAddress models.Address, pickupDate time.Time, weight int, marketCode models.MarketCode) (*time.Time, error) { // Okay, so this is something to get us able to take care of the 20 day condition over in the gdoc linked in this // story: https://dp3.atlassian.net/browse/MB-1141 // We unfortunately didn't get a lot of guidance regarding vicinity. So for now we're taking zip codes that are the @@ -1197,8 +1197,9 @@ func CalculateRequiredDeliveryDate(appCtx appcontext.AppContext, planner route.P "99615", "99619", "99624", "99643", "99644", "99697", "99650", "99801", "99802", "99803", "99811", "99812", "99950", "99824", "99850", "99901", "99928", "99950", "99835"} + internationalShipment := marketCode == models.MarketCodeInternational // Get a distance calculation between pickup and destination addresses. - distance, err := planner.ZipTransitDistance(appCtx, pickupAddress.PostalCode, destinationAddress.PostalCode, false, false) + distance, err := planner.ZipTransitDistance(appCtx, pickupAddress.PostalCode, destinationAddress.PostalCode, false, internationalShipment) if err != nil { return nil, err } diff --git a/pkg/services/mto_shipment/rules.go b/pkg/services/mto_shipment/rules.go index 46663cc2c00..738db7f8d61 100644 --- a/pkg/services/mto_shipment/rules.go +++ b/pkg/services/mto_shipment/rules.go @@ -343,7 +343,7 @@ func checkPrimeValidationsOnModel(planner route.Planner) validator { weight = older.NTSRecordedWeight } requiredDeliveryDate, err := CalculateRequiredDeliveryDate(appCtx, planner, *latestPickupAddress, - *latestDestinationAddress, *latestSchedPickupDate, weight.Int()) + *latestDestinationAddress, *latestSchedPickupDate, weight.Int(), older.MarketCode) if err != nil { verrs.Add("requiredDeliveryDate", err.Error()) } diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index 396f94a12e9..259015e210c 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -205,7 +205,7 @@ func (f *shipmentApprover) setRequiredDeliveryDate(appCtx appcontext.AppContext, deliveryLocation = shipment.DestinationAddress weight = shipment.PrimeEstimatedWeight.Int() } - requiredDeliveryDate, calcErr := CalculateRequiredDeliveryDate(appCtx, f.planner, *pickupLocation, *deliveryLocation, *shipment.ScheduledPickupDate, weight) + requiredDeliveryDate, calcErr := CalculateRequiredDeliveryDate(appCtx, f.planner, *pickupLocation, *deliveryLocation, *shipment.ScheduledPickupDate, weight, shipment.MarketCode) if calcErr != nil { return calcErr } diff --git a/pkg/testdatagen/scenario/shared.go b/pkg/testdatagen/scenario/shared.go index d5425b5cef3..15e8836bc1d 100644 --- a/pkg/testdatagen/scenario/shared.go +++ b/pkg/testdatagen/scenario/shared.go @@ -4932,7 +4932,7 @@ func createHHGWithPaymentServiceItems( "94535", "94535", false).Return(348, nil).Times(2) // called for zip 5 domestic linehaul service item - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false, false).Return(348, nil).Once() + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "94535", "94535", false, false).Return(348, nil).Times(2) // called for domestic shorthaul service item planner.On("Zip5TransitDistance", mock.AnythingOfType("*appcontext.appContext"), From 66d7380aa7521bc1aa88e7cbc88fd9a1edbb86b6 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 19 Dec 2024 22:46:41 +0000 Subject: [PATCH 24/52] tests --- pkg/services/mto_shipment/mto_shipment_updater_test.go | 2 +- pkg/services/mto_shipment/shipment_approver_test.go | 2 +- .../shipment_address_update_requester_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 05ea51d229d..e820cc98258 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -466,7 +466,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { "50314", "99505", true, - false, + true, ).Return(1000, nil) ghcDomesticTransitTime := models.GHCDomesticTransitTime{ diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 3b4f0f9c078..02645ff33fa 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -286,7 +286,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { "50314", "99505", true, - false, + true, ).Return(1000, nil) // Approve international shipment diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index d8af5b02950..2cdbebbadbc 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -1021,7 +1021,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp mock.Anything, mock.Anything, true, - false, + true, ).Return(300, nil) newDestUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99703") From db36c6a07dd3c8791e5250b1e5f29bafe63de90c Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 13:48:13 +0000 Subject: [PATCH 25/52] adjusting tests --- .../mto_shipment/mto_shipment_updater_test.go | 2 +- pkg/services/mto_shipment/shipment_approver_test.go | 13 +++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index e820cc98258..9ef945750f2 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -464,7 +464,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50314", - "99505", + "97220", true, true, ).Return(1000, nil) diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 02645ff33fa..5984cbb71e8 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -191,7 +191,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 and update pricing when there is estimated weight", func() { + suite.Run("If the international mtoShipment is approved successfully it should create pre approved mtoServiceItems and should NOT update pricing without port data", func() { move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ { Model: models.Move{ @@ -279,15 +279,8 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { mock.Anything, mock.Anything, false, - false, - ).Return(500, nil) - planner.On("ZipTransitDistance", - mock.AnythingOfType("*appcontext.appContext"), - "50314", - "99505", - true, true, - ).Return(1000, nil) + ).Return(500, nil) // Approve international shipment shipmentApprover := NewShipmentApprover(shipmentRouter, serviceItemCreator, planner, moveWeights) @@ -311,7 +304,7 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { actualReServiceCode := serviceItems[i].ReService.Code suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) // because the estimated weight is provided, estimated pricing should be updated - suite.NotNil(serviceItems[i].PricingEstimate) + suite.Nil(serviceItems[i].PricingEstimate) } }) From 8558ced0f973a72b31e22e78fbf1b5e608e6db60 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 14:43:00 +0000 Subject: [PATCH 26/52] comments --- pkg/services/mto_shipment/mto_shipment_updater_test.go | 4 ++-- .../shipment_address_update_requester_test.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 9ef945750f2..20b9f1fc225 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -459,7 +459,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { suite.Equal(updatedShipment.MarketCode, models.MarketCodeInternational) }) - suite.Run("Successful update on international shipment with estimated weight results in the of basic pricing service items", func() { + suite.Run("Successful update on international shipment with estimated weight results in the update of estimated pricing for basic service items", func() { setupTestData() planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), @@ -651,7 +651,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { suite.Equal(4, len(serviceItems)) for i := 0; i < len(serviceItems); i++ { - // because the estimated weight is provided, estimated pricing should be updated + // because the estimated weight is provided & POEFSC has a port location, estimated pricing should be updated suite.NotNil(serviceItems[i].PricingEstimate) } }) diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index 2cdbebbadbc..95f1a464748 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -974,6 +974,7 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp }, }, }, nil) + // POEFSC needs a port location portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ { Model: models.Port{ From 005982011eda7e9ef9fbb7f4564d663aaf712236 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 15:08:52 +0000 Subject: [PATCH 27/52] flaky server test fix --- .../mto_shipment/mto_shipment_updater_test.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 20b9f1fc225..3e5ee322377 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -3188,7 +3188,16 @@ func (suite *MTOShipmentServiceSuite) TestUpdateStatusServiceItems() { err = appCtx.DB().EagerPreload("ReService").Where("mto_shipment_id = ?", updatedShipment.ID).All(&serviceItems) suite.NoError(err) - suite.Equal(models.ReServiceCodeDLH, serviceItems[0].ReService.Code) + foundDLH := false + for _, serviceItem := range serviceItems { + if serviceItem.ReService.Code == models.ReServiceCodeDLH { + foundDLH = true + break + } + } + + // at least one service item should have the DLH code + suite.True(foundDLH, "Expected to find at least one service item with ReService code DLH") }) suite.Run("Shipments with same origin/destination ZIP3 have shorthaul service item", func() { From 1282a6ea486183541f688d404842001c9b55a3ab Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 16:54:26 +0000 Subject: [PATCH 28/52] adding in estimated pricing update when port is updated, added tests --- pkg/models/mto_service_items.go | 4 +- .../mto_service_item_updater.go | 31 +++ .../mto_service_item_updater_test.go | 197 ++++++++++++++++++ .../mto_shipment/mto_shipment_updater.go | 5 +- .../port_location/port_location_fetcher.go | 2 +- 5 files changed, 234 insertions(+), 5 deletions(-) diff --git a/pkg/models/mto_service_items.go b/pkg/models/mto_service_items.go index 822e568f227..446c822c1ee 100644 --- a/pkg/models/mto_service_items.go +++ b/pkg/models/mto_service_items.go @@ -154,7 +154,9 @@ func FetchServiceItem(db *pop.Connection, serviceItemID uuid.UUID) (MTOServiceIt err := db.Eager("SITDestinationOriginalAddress", "SITDestinationFinalAddress", "ReService", - "CustomerContacts").Where("id = ?", serviceItemID).First(&serviceItem) + "CustomerContacts", + "MTOShipment.PickupAddress", + "MTOShipment.DestinationAddress").Where("id = ?", serviceItemID).First(&serviceItem) if err != nil { if errors.Cause(err).Error() == RecordNotFoundErrorString { 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 544d1374ecd..049e673e79f 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -612,6 +612,37 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItem( // Make the update and create a InvalidInputError if there were validation issues verrs, updateErr := txnAppCtx.DB().ValidateAndUpdate(validServiceItem) + // if the port information was updated, then we need to update the basic service item pricing since distance has changed + // this only applies to international shipments + if oldServiceItem.POELocationID != mtoServiceItem.POELocationID || oldServiceItem.PODLocationID != mtoServiceItem.PODLocationID { + shipment := oldServiceItem.MTOShipment + if shipment.PickupAddress != nil && shipment.DestinationAddress != nil && + (mtoServiceItem.POELocation.UsPostRegionCity.UsprZipID != "" || mtoServiceItem.PODLocation.UsPostRegionCity.UsprZipID != "") { + var pickupZip string + var destZip string + // if the port type is POEFSC this means the shipment is CONUS -> OCONUS (pickup -> port) + // if the port type is PODFSC this means the shipment is OCONUS -> CONUS (port -> destination) + if mtoServiceItem.POELocation != nil { + pickupZip = shipment.PickupAddress.PostalCode + destZip = mtoServiceItem.POELocation.UsPostRegionCity.UsprZipID + } else if mtoServiceItem.PODLocation != nil { + pickupZip = mtoServiceItem.PODLocation.UsPostRegionCity.UsprZipID + destZip = shipment.DestinationAddress.PostalCode + } + // we need to get the mileage from DTOD first, the db proc will consume that + mileage, err := p.planner.ZipTransitDistance(appCtx, pickupZip, destZip, true, true) + if err != nil { + return err + } + + // update the service item pricing if relevant fields have changed + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, mileage) + if err != nil { + return err + } + } + } + // If there were validation errors create an InvalidInputError type if verrs != nil && verrs.HasAny() { return apperror.NewInvalidInputError(validServiceItem.ID, updateErr, verrs, "Invalid input found while updating the service item.") 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 c41540db364..efb730a8f18 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 @@ -1393,6 +1393,203 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { suite.Error(err) suite.IsType(apperror.UnprocessableEntityError{}, err) }) + + suite.Run("Successful update of port service item with updated pricing estimates of basic iHHG service items ", func() { + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "50314", + "98158", + true, + true, + ).Return(1000, nil) + + ghcDomesticTransitTime := models.GHCDomesticTransitTime{ + MaxDaysTransitTime: 12, + WeightLbsLower: 0, + WeightLbsUpper: 10000, + DistanceMilesLower: 0, + DistanceMilesUpper: 10000, + } + _, _ = suite.DB().ValidateAndCreate(&ghcDomesticTransitTime) + + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + + pickupUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "50314") + suite.FatalNoError(err) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &pickupUSPRC.ID, + }, + }, + }, nil) + + destUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + suite.FatalNoError(err) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, + }, + }, + }, nil) + + pickupDate := time.Now() + requestedPickup := time.Now() + estimatedWeight := unit.Pound(1212) + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + ScheduledPickupDate: &pickupDate, + RequestedPickupDate: &requestedPickup, + PrimeEstimatedWeight: &estimatedWeight, + }, + }, + { + Model: move, + LinkOnly: true, + }, + }, nil) + + // building service items with NO pricing estimates + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeISLH, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHUPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + poefsc := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + { + Model: portLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfEmbarkation, + }, + }, nil) + + eTag := etag.GenerateEtag(poefsc.UpdatedAt) + + // update the port + newServiceItemPrime := poefsc + newServiceItemPrime.POELocation.Port.PortCode = "SEA" + + // Update MTO service item + _, err = updater.UpdateMTOServiceItemPrime(suite.AppContextForTest(), &newServiceItemPrime, planner, shipment, eTag) + suite.NoError(err) + + // checking the service item data + var serviceItems []models.MTOServiceItem + err = suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", shipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err) + + suite.Equal(4, len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + // because the estimated weight is provided & POEFSC has a port location now, estimated pricing should be updated + suite.NotNil(serviceItems[i].PricingEstimate) + } + }) } func (suite *MTOServiceItemServiceSuite) TestValidateUpdateMTOServiceItem() { diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index acb2aec3c23..dde0c897340 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -855,8 +855,7 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, // we will compare data here to see if we even need to update the pricing if newShipment.PrimeEstimatedWeight != nil && newShipment.MarketCode == models.MarketCodeInternational && - (newShipment.PrimeEstimatedWeight != dbShipment.PrimeEstimatedWeight || - newShipment.PickupAddress != nil && newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || + (newShipment.PickupAddress != nil && newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || newShipment.DestinationAddress != nil && newShipment.DestinationAddress.PostalCode != dbShipment.DestinationAddress.PostalCode || newShipment.RequestedPickupDate != nil && newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { @@ -864,7 +863,7 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, if err != nil { return err } - // if we don't have the port data, then we won't worry about pricing + // if we don't have the port data, then we won't worry about pricing because we need the distance from/to the ports if portZip != nil && portType != nil { var pickupZip string var destZip string diff --git a/pkg/services/port_location/port_location_fetcher.go b/pkg/services/port_location/port_location_fetcher.go index fb26549934f..9d25b2d94a2 100644 --- a/pkg/services/port_location/port_location_fetcher.go +++ b/pkg/services/port_location/port_location_fetcher.go @@ -17,7 +17,7 @@ func NewPortLocationFetcher() services.PortLocationFetcher { func (p *portLocationFetcher) FetchPortLocationByPortCode(appCtx appcontext.AppContext, portCode string) (*models.PortLocation, error) { portLocation := models.PortLocation{} - err := appCtx.DB().Eager("Port").Where("is_active = TRUE").InnerJoin("ports p", "port_id = p.id").Where("p.port_code = $1", portCode).First(&portLocation) + err := appCtx.DB().Eager("Port", "UsPostRegionCity").Where("is_active = TRUE").InnerJoin("ports p", "port_id = p.id").Where("p.port_code = $1", portCode).First(&portLocation) if err != nil { return nil, apperror.NewQueryError("PortLocation", err, "") } From 0bd2bdedda8246bf15b95a4606127e6088ad94b2 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 18:27:42 +0000 Subject: [PATCH 29/52] fixing test and operand --- pkg/services/mto_shipment/mto_shipment_updater.go | 6 +++--- pkg/services/mto_shipment/mto_shipment_updater_test.go | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index dde0c897340..17f9179fddd 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -853,9 +853,9 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, // if the shipment has an estimated weight, we need to update the service item pricing // we only need to do this if the estimated weight, primary addresses, and pickup date are being updated since those all impact pricing // we will compare data here to see if we even need to update the pricing - if newShipment.PrimeEstimatedWeight != nil && - newShipment.MarketCode == models.MarketCodeInternational && - (newShipment.PickupAddress != nil && newShipment.PickupAddress.PostalCode != dbShipment.PickupAddress.PostalCode || + 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.RequestedPickupDate != nil && newShipment.RequestedPickupDate.Format("2006-01-02") != dbShipment.RequestedPickupDate.Format("2006-01-02")) { diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 3e5ee322377..993cae750f4 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -461,6 +461,14 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { suite.Run("Successful update on international shipment with estimated weight results in the update of estimated pricing for basic service items", func() { setupTestData() + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "50314", + "99505", + false, + true, + ).Return(1000, nil) + planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), "50314", @@ -528,6 +536,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { DestinationAddressID: &destinationAddress.ID, ScheduledPickupDate: &pickupDate, RequestedPickupDate: &requestedPickup, + MarketCode: models.MarketCodeInternational, }, }, { From 6126d4644d1334f492a4d619ac99c997545ddbad Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 26 Dec 2024 22:49:15 +0000 Subject: [PATCH 30/52] nil check --- pkg/services/mto_service_item/mto_service_item_updater.go | 3 ++- 1 file changed, 2 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 049e673e79f..b4491ea0ad7 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -617,7 +617,8 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItem( if oldServiceItem.POELocationID != mtoServiceItem.POELocationID || oldServiceItem.PODLocationID != mtoServiceItem.PODLocationID { shipment := oldServiceItem.MTOShipment if shipment.PickupAddress != nil && shipment.DestinationAddress != nil && - (mtoServiceItem.POELocation.UsPostRegionCity.UsprZipID != "" || mtoServiceItem.PODLocation.UsPostRegionCity.UsprZipID != "") { + (mtoServiceItem.POELocation != nil && mtoServiceItem.POELocation.UsPostRegionCity.UsprZipID != "" || + mtoServiceItem.PODLocation != nil && mtoServiceItem.PODLocation.UsPostRegionCity.UsprZipID != "") { var pickupZip string var destZip string // if the port type is POEFSC this means the shipment is CONUS -> OCONUS (pickup -> port) From 908c670f72b6ca8e4f7db993a50d0fd62ab90074 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 3 Jan 2025 18:48:19 +0000 Subject: [PATCH 31/52] initial commit, functionality added, tests added, migration updated --- migrations/app/migrations_manifest.txt | 1 + ...ng_proc_to_use_local_price_variable.up.sql | 129 +++++++++++ pkg/models/mto_shipments.go | 2 +- .../mto_service_item_updater.go | 2 +- .../mto_shipment/mto_shipment_updater.go | 10 +- .../mto_shipment/mto_shipment_updater_test.go | 203 +++++++++++++++++- .../mto_shipment/shipment_approver.go | 8 +- .../mto_shipment/shipment_approver_test.go | 1 - .../shipment_address_update_requester.go | 8 +- .../shipment_address_update_requester_test.go | 203 ++++++++++++++++++ src/setupProxy.js | 2 +- 11 files changed, 558 insertions(+), 11 deletions(-) create mode 100644 migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 29248cb93ef..c3e7c7eff9d 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1061,3 +1061,4 @@ 20241227153723_remove_empty_string_emplid_values.up.sql 20241230190638_remove_AK_zips_from_zip3.up.sql 20241230190647_add_missing_AK_zips_to_zip3_distances.up.sql +20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql diff --git a/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql b/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql new file mode 100644 index 00000000000..a721d714ef6 --- /dev/null +++ b/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql @@ -0,0 +1,129 @@ +-- updating the pricing proc to use local variables when updating service items +-- there was an issue where it was retaining the previous value when the port fuel surcharges couldn't be priced but were updating anyway +CREATE OR REPLACE PROCEDURE update_service_item_pricing( + shipment_id UUID, + mileage INT +) AS +' +DECLARE + shipment RECORD; + service_item RECORD; + escalated_price NUMERIC; + estimated_price NUMERIC; + o_rate_area_id UUID; + d_rate_area_id UUID; + contract_id UUID; + service_code TEXT; + o_zip_code TEXT; + d_zip_code TEXT; + distance NUMERIC; -- This will be replaced by mileage + estimated_fsc_multiplier NUMERIC; + fuel_price NUMERIC; + cents_above_baseline NUMERIC; + price_difference NUMERIC; +BEGIN + SELECT ms.id, ms.pickup_address_id, ms.destination_address_id, ms.requested_pickup_date, ms.prime_estimated_weight + INTO shipment + FROM mto_shipments ms + WHERE ms.id = shipment_id; + + IF shipment IS NULL THEN + RAISE EXCEPTION ''Shipment with ID % not found'', shipment_id; + END IF; + + -- exit the proc if prime_estimated_weight is NULL + IF shipment.prime_estimated_weight IS NULL THEN + RETURN; + END IF; + + -- loop through service items in the shipment + FOR service_item IN + SELECT si.id, si.re_service_id + FROM mto_service_items si + WHERE si.mto_shipment_id = shipment_id + LOOP + -- get the service code for the current service item to determine calculation + SELECT code + INTO service_code + FROM re_services + WHERE id = service_item.re_service_id; + + CASE + WHEN service_code IN (''ISLH'', ''UBP'') THEN + contract_id := get_contract_id(shipment.requested_pickup_date); + o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id, contract_id); + d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id, contract_id); + escalated_price := calculate_escalated_price(o_rate_area_id, d_rate_area_id, service_item.re_service_id, contract_id, service_code); + + IF shipment.prime_estimated_weight IS NOT NULL THEN + estimated_price := ROUND((escalated_price * (shipment.prime_estimated_weight / 100)::NUMERIC) * 100, 0); + RAISE NOTICE ''%: Received estimated price of % (% * (% / 100)) cents'', service_code, estimated_price, escalated_price, shipment.prime_estimated_weight; + -- update the pricing_estimate value in mto_service_items + UPDATE mto_service_items + SET pricing_estimate = estimated_price + WHERE id = service_item.id; + END IF; + + WHEN service_code IN (''IHPK'', ''IUBPK'') THEN + -- perform IHPK/IUBPK-specific logic (no destination rate area) + contract_id := get_contract_id(shipment.requested_pickup_date); + o_rate_area_id := get_rate_area_id(shipment.pickup_address_id, service_item.re_service_id, contract_id); + escalated_price := calculate_escalated_price(o_rate_area_id, NULL, service_item.re_service_id, contract_id, service_code); + + IF shipment.prime_estimated_weight IS NOT NULL THEN + estimated_price := ROUND((escalated_price * (shipment.prime_estimated_weight / 100)::NUMERIC) * 100, 0); + RAISE NOTICE ''%: Received estimated price of % (% * (% / 100)) cents'', service_code, estimated_price, escalated_price, shipment.prime_estimated_weight; + -- update the pricing_estimate value in mto_service_items + UPDATE mto_service_items + SET pricing_estimate = estimated_price + WHERE id = service_item.id; + END IF; + + WHEN service_code IN (''IHUPK'', ''IUBUPK'') THEN + -- perform IHUPK/IUBUPK-specific logic (no origin rate area) + contract_id := get_contract_id(shipment.requested_pickup_date); + d_rate_area_id := get_rate_area_id(shipment.destination_address_id, service_item.re_service_id, contract_id); + escalated_price := calculate_escalated_price(NULL, d_rate_area_id, service_item.re_service_id, contract_id, service_code); + + IF shipment.prime_estimated_weight IS NOT NULL THEN + estimated_price := ROUND((escalated_price * (shipment.prime_estimated_weight / 100)::NUMERIC) * 100, 0); + RAISE NOTICE ''%: Received estimated price of % (% * (% / 100)) cents'', service_code, estimated_price, escalated_price, shipment.prime_estimated_weight; + -- update the pricing_estimate value in mto_service_items + UPDATE mto_service_items + SET pricing_estimate = estimated_price + WHERE id = service_item.id; + END IF; + + WHEN service_code IN (''POEFSC'', ''PODFSC'') THEN + -- use the passed mileage parameter + distance = mileage; + -- if we do not have the distance, then we cannot price + IF distance IS NULL THEN + RETURN; + END IF; + + -- getting FSC multiplier from re_fsc_multipliers + estimated_fsc_multiplier := get_fsc_multiplier(shipment.prime_estimated_weight); + + fuel_price := get_fuel_price(shipment.requested_pickup_date); + + price_difference := calculate_price_difference(fuel_price); + + -- calculate estimated price, return as cents + IF estimated_fsc_multiplier IS NOT NULL AND distance IS NOT NULL THEN + cents_above_baseline := distance * estimated_fsc_multiplier; + RAISE NOTICE ''Distance: % * FSC Multipler: % = $% cents above baseline of $2.50'', distance, estimated_fsc_multiplier, cents_above_baseline; + RAISE NOTICE ''The fuel price is % cents above the baseline ($% - $2.50 baseline)'', price_difference, fuel_price; + estimated_price := ROUND((cents_above_baseline * price_difference) * 100); + RAISE NOTICE ''Received estimated price of % cents for service_code: %.'', estimated_price, service_code; + + -- update the pricing_estimate value in mto_service_items + UPDATE mto_service_items + SET pricing_estimate = estimated_price + WHERE id = service_item.id; + END IF; + END CASE; + END LOOP; +END; +' +LANGUAGE plpgsql; \ No newline at end of file diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index 002959be9cc..fe50077f8c0 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -401,7 +401,7 @@ func CreateApprovedServiceItemsForShipment(db *pop.Connection, shipment *MTOShip // a db stored proc that will handle updating the pricing_estimate columns of basic service items for shipment types: // iHHG // iUB -func UpdateEstimatedPricingForShipmentBasicServiceItems(db *pop.Connection, shipment *MTOShipment, mileage int) error { +func UpdateEstimatedPricingForShipmentBasicServiceItems(db *pop.Connection, shipment *MTOShipment, mileage *int) error { err := db.RawQuery("CALL update_service_item_pricing($1, $2)", shipment.ID, mileage).Exec() if err != nil { return fmt.Errorf("error updating estimated pricing for shipment's service items: %w", err) 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 b4491ea0ad7..b14f266fc4b 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -637,7 +637,7 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItem( } // update the service item pricing if relevant fields have changed - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, mileage) + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, &mileage) if err != nil { return err } diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 17f9179fddd..b4b0d266e0a 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -863,7 +863,7 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, if err != nil { return err } - // if we don't have the port data, then we won't worry about pricing because we need the distance from/to the ports + // if we don't have the port data, then we won't worry about pricing POEFSC/PODFSC because we need the distance from/to the ports if portZip != nil && portType != nil { var pickupZip string var destZip string @@ -883,7 +883,13 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, } // update the service item pricing if relevant fields have changed - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment, mileage) + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment, &mileage) + if err != nil { + return err + } + } else { + // if we don't have the port data, that's okay - we can update the other service items except for PODFSC/POEFSC + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), newShipment, nil) if err != nil { return err } diff --git a/pkg/services/mto_shipment/mto_shipment_updater_test.go b/pkg/services/mto_shipment/mto_shipment_updater_test.go index 993cae750f4..ba8cc3b7b89 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater_test.go +++ b/pkg/services/mto_shipment/mto_shipment_updater_test.go @@ -468,11 +468,10 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { false, true, ).Return(1000, nil) - planner.On("ZipTransitDistance", mock.AnythingOfType("*appcontext.appContext"), - "50314", "97220", + "99505", true, true, ).Return(1000, nil) @@ -638,7 +637,7 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { { Model: portLocation, LinkOnly: true, - Type: &factory.PortLocations.PortOfEmbarkation, + Type: &factory.PortLocations.PortOfDebarkation, }, }, nil) @@ -665,6 +664,204 @@ func (suite *MTOShipmentServiceSuite) TestMTOShipmentUpdater() { } }) + suite.Run("Successful update on international shipment with estimated weight results in the update of estimated pricing for basic service items except for port fuel surcharge", func() { + setupTestData() + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "50314", + "99505", + false, + true, + ).Return(1000, nil) + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "50314", + "97220", + true, + true, + ).Return(1000, nil) + + ghcDomesticTransitTime := models.GHCDomesticTransitTime{ + MaxDaysTransitTime: 12, + WeightLbsLower: 0, + WeightLbsUpper: 10000, + DistanceMilesLower: 0, + DistanceMilesUpper: 10000, + } + _, _ = suite.DB().ValidateAndCreate(&ghcDomesticTransitTime) + + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + + pickupUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "50314") + suite.FatalNoError(err) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &pickupUSPRC.ID, + }, + }, + }, nil) + + destUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + suite.FatalNoError(err) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, + }, + }, + }, nil) + + pickupDate := now.AddDate(0, 0, 10) + requestedPickup := time.Now() + dbShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + PrimeEstimatedWeight: nil, + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + ScheduledPickupDate: &pickupDate, + RequestedPickupDate: &requestedPickup, + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + }, nil) + + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: dbShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeISLH, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: dbShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: dbShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHUPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + + // this will not have a port location and pricing shouldn't be updated + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: dbShipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodePODFSC, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: nil, + }, + }, + }, nil) + + eTag := etag.GenerateEtag(dbShipment.UpdatedAt) + + shipment := models.MTOShipment{ + ID: dbShipment.ID, + PrimeEstimatedWeight: &primeEstimatedWeight, + } + + session := auth.Session{} + _, err = mtoShipmentUpdaterPrime.UpdateMTOShipment(suite.AppContextWithSessionForTest(&session), &shipment, eTag, "test") + suite.NoError(err) + + // checking the service item data + var serviceItems []models.MTOServiceItem + err = suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", dbShipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err) + + suite.Equal(4, len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + if serviceItems[i].ReService.Code != models.ReServiceCodePODFSC { + suite.NotNil(serviceItems[i].PricingEstimate) + } else if serviceItems[i].ReService.Code == models.ReServiceCodePODFSC { + suite.Nil(serviceItems[i].PricingEstimate) + } + } + }) + suite.Run("Successful update to a minimal MTO shipment", func() { setupTestData() diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index 259015e210c..34021fcb3e2 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -112,7 +112,13 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen } // update the service item pricing if relevant fields have changed - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment, mileage) + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment, &mileage) + if err != nil { + return err + } + } else { + // if we don't have the port data, that's okay - we can update the other service items except for PODFSC/POEFSC + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), shipment, nil) if err != nil { return err } diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 5984cbb71e8..3744a03691f 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -303,7 +303,6 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { for i := 0; i < len(serviceItems); i++ { actualReServiceCode := serviceItems[i].ReService.Code suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) - // because the estimated weight is provided, estimated pricing should be updated suite.Nil(serviceItems[i].PricingEstimate) } }) diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index d43dced8a8d..a0ed36fccdd 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -631,7 +631,13 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc } // update the service item pricing if relevant fields have changed - err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, mileage) + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, &mileage) + if err != nil { + return err + } + } else { + // if we don't have the port data, that's okay - we can update the other service items except for PODFSC/POEFSC + err = models.UpdateEstimatedPricingForShipmentBasicServiceItems(appCtx.DB(), &shipment, nil) if err != nil { return err } diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index 95f1a464748..4330b13f9eb 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -1079,6 +1079,209 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUp suite.NotEqual(serviceItems[i].PricingEstimate, &initialPrice) } }) + suite.Run("On approval - successfully update estimated pricing on all basic iHHG service items except for POEFSC when port isn't set", func() { + ghcDomesticTransitTime := models.GHCDomesticTransitTime{ + MaxDaysTransitTime: 12, + WeightLbsLower: 0, + WeightLbsUpper: 10000, + DistanceMilesLower: 0, + DistanceMilesUpper: 10000, + } + _, _ = suite.DB().ValidateAndCreate(&ghcDomesticTransitTime) + + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + pickupUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "50314") + suite.FatalNoError(err) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &pickupUSPRC.ID, + }, + }, + }, nil) + + destUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + suite.FatalNoError(err) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, + }, + }, + }, nil) + + now := time.Now() + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + PrimeEstimatedWeight: models.PoundPointer(4000), + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + ScheduledPickupDate: &now, + RequestedPickupDate: &now, + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + }, nil) + + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeISLH, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + }, + }, + }, nil) + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIHUPK, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + PricingEstimate: models.CentPointer(1000), + }, + }, + }, nil) + // no port data + factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + }, + }, + }, nil) + + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + false, + ).Return(300, nil) + + newDestUSPRC, err := models.FindByZipCode(suite.AppContextForTest().DB(), "99703") + suite.FatalNoError(err) + factory.BuildShipmentAddressUpdate(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: models.Address{ + StreetAddress1: "Cold Ave.", + City: "Fairbanks", + State: "AK", + PostalCode: "99703", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &newDestUSPRC.ID, + }, + Type: &factory.Addresses.NewAddress, + }, + }, []factory.Trait{factory.GetTraitShipmentAddressUpdateRequested}) + + officeRemarks := "Changing to another OCONUS address" + update, err := addressUpdateRequester.ReviewShipmentAddressChange(suite.AppContextForTest(), shipment.ID, "APPROVED", officeRemarks) + + suite.NoError(err) + suite.NotNil(update) + suite.Equal(models.ShipmentAddressUpdateStatusApproved, update.Status) + + // checking out the service items + var serviceItems []models.MTOServiceItem + err = suite.AppContextForTest().DB().EagerPreload("ReService").Where("mto_shipment_id = ?", shipment.ID).Order("created_at asc").All(&serviceItems) + suite.NoError(err) + + suite.Equal(4, len(serviceItems)) + for i := 0; i < len(serviceItems); i++ { + if serviceItems[i].ReService.Code != models.ReServiceCodePOEFSC { + suite.NotNil(serviceItems[i].PricingEstimate) + } else if serviceItems[i].ReService.Code == models.ReServiceCodePOEFSC { + suite.Nil(serviceItems[i].PricingEstimate) + } + } + }) } func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUpdateRequestChangedPricing() { diff --git a/src/setupProxy.js b/src/setupProxy.js index 1f34bb64ffc..2e2d0f6d6a4 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -11,7 +11,7 @@ module.exports = (app) => { app.use('/testharness', createProxyMiddleware({ target: 'http://milmovelocal:8080/testharness' })); app.use('/storage', createProxyMiddleware({ target: 'http://milmovelocal:8080/storage' })); app.use('/devlocal-auth', createProxyMiddleware({ target: 'http://milmovelocal:8080/devlocal-auth' })); - app.use('/auth/**', createProxyMiddleware({ target: 'http://milmovelocal:8080/auth/**' })); + app.use('/auth', createProxyMiddleware({ target: 'http://milmovelocal:8080/auth' })); app.use('/logout', createProxyMiddleware({ target: 'http://milmovelocal:8080/logout' })); app.use('/downloads', createProxyMiddleware({ target: 'http://milmovelocal:8080/downloads' })); app.use('/debug/**', createProxyMiddleware({ target: 'http://milmovelocal:8080/debug/**' })); From a2e459ffa0f000ec68b435a9f1100afa92ce44ea Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 3 Jan 2025 19:00:06 +0000 Subject: [PATCH 32/52] reverting setupProxy back since it is not in main --- src/setupProxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setupProxy.js b/src/setupProxy.js index 2e2d0f6d6a4..1f34bb64ffc 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -11,7 +11,7 @@ module.exports = (app) => { app.use('/testharness', createProxyMiddleware({ target: 'http://milmovelocal:8080/testharness' })); app.use('/storage', createProxyMiddleware({ target: 'http://milmovelocal:8080/storage' })); app.use('/devlocal-auth', createProxyMiddleware({ target: 'http://milmovelocal:8080/devlocal-auth' })); - app.use('/auth', createProxyMiddleware({ target: 'http://milmovelocal:8080/auth' })); + app.use('/auth/**', createProxyMiddleware({ target: 'http://milmovelocal:8080/auth/**' })); app.use('/logout', createProxyMiddleware({ target: 'http://milmovelocal:8080/logout' })); app.use('/downloads', createProxyMiddleware({ target: 'http://milmovelocal:8080/downloads' })); app.use('/debug/**', createProxyMiddleware({ target: 'http://milmovelocal:8080/debug/**' })); From 499c45aaf42ebb2b7ebcce966b82c746650312ef Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Mon, 6 Jan 2025 20:45:38 +0000 Subject: [PATCH 33/52] adjust migration, tests --- ..._update_pricing_proc_to_use_local_price_variable.up.sql | 4 ---- pkg/services/mto_shipment/shipment_approver_test.go | 7 ++++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql b/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql index a721d714ef6..d5b3a911dc3 100644 --- a/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql +++ b/migrations/app/schema/20250103180420_update_pricing_proc_to_use_local_price_variable.up.sql @@ -97,10 +97,6 @@ BEGIN WHEN service_code IN (''POEFSC'', ''PODFSC'') THEN -- use the passed mileage parameter distance = mileage; - -- if we do not have the distance, then we cannot price - IF distance IS NULL THEN - RETURN; - END IF; -- getting FSC multiplier from re_fsc_multipliers estimated_fsc_multiplier := get_fsc_multiplier(shipment.prime_estimated_weight); diff --git a/pkg/services/mto_shipment/shipment_approver_test.go b/pkg/services/mto_shipment/shipment_approver_test.go index 3744a03691f..9444dd7cb2c 100644 --- a/pkg/services/mto_shipment/shipment_approver_test.go +++ b/pkg/services/mto_shipment/shipment_approver_test.go @@ -303,7 +303,12 @@ func (suite *MTOShipmentServiceSuite) TestApproveShipment() { for i := 0; i < len(serviceItems); i++ { actualReServiceCode := serviceItems[i].ReService.Code suite.True(slices.Contains(expectedReserviceCodes, actualReServiceCode)) - suite.Nil(serviceItems[i].PricingEstimate) + // we should have pricing data on all but the POEFSC since we don't have the port data yet + if serviceItems[i].ReService.Code != models.ReServiceCodePOEFSC { + suite.NotNil(serviceItems[i].PricingEstimate) + } else if serviceItems[i].ReService.Code == models.ReServiceCodePOEFSC { + suite.Nil(serviceItems[i].PricingEstimate) + } } }) From 4221cc2b3b4816185df8b97384167229261d98e9 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 26 Dec 2024 21:16:44 +0000 Subject: [PATCH 34/52] initial commit, added pricers, waiting on ordering issue regarding packing/unpacking --- migrations/app/migrations_manifest.txt | 1 + ...aram_values_to_service_params_table.up.sql | 103 +++++++++++++ .../allowed_payment_service_item_params.go | 15 ++ pkg/handlers/primeapi/payment_request_test.go | 14 -- pkg/services/ghc_rate_engine.go | 32 ++++ .../ghcrateengine/fuel_surcharge_pricer.go | 2 +- .../ghcrateengine/intl_hhg_pack_pricer.go | 56 +++++++ .../ghcrateengine/intl_hhg_unpack_pricer.go | 56 +++++++ .../intl_port_fuel_surcharge_pricer.go | 111 ++++++++++++++ .../intl_shipping_and_linehaul_pricer.go | 137 ++++++++++++++++++ .../ghcrateengine/pricer_helpers_intl.go | 86 +++++++++++ .../ghcrateengine/pricer_query_helpers.go | 18 +++ .../ghcrateengine/service_item_pricer.go | 10 ++ pkg/services/ghcrateengine/shared.go | 3 + .../payment_request_creator.go | 1 - 15 files changed, 629 insertions(+), 16 deletions(-) create mode 100644 migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql create mode 100644 pkg/services/ghcrateengine/intl_hhg_pack_pricer.go create mode 100644 pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go create mode 100644 pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go create mode 100644 pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go create mode 100644 pkg/services/ghcrateengine/pricer_helpers_intl.go diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 32afaa072da..be5080ccd3d 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1058,6 +1058,7 @@ 20241217180136_add_AK_zips_to_zip3_distances.up.sql 20241218201833_add_PPPO_BASE_ELIZABETH.up.sql 20241220171035_add_additional_AK_zips_to_zip3_distances.up.sql +20241226173330_add_intl_param_values_to_service_params_table.up.sql 20241227153723_remove_empty_string_emplid_values.up.sql 20241227202424_insert_transportation_offices_camp_pendelton.up.sql 20241230190638_remove_AK_zips_from_zip3.up.sql diff --git a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql new file mode 100644 index 00000000000..26ccf6dff90 --- /dev/null +++ b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql @@ -0,0 +1,103 @@ + +-- inserting params for PODFSC +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('9848562b-50c1-4e6e-aef0-f9539bf243fa'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','adeb57e5-6b1c-4c0f-b5c9-9e57e600303f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('9c244768-07ce-4368-936b-0ac14a8078a4'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','14a93209-370d-42f3-8ca2-479c953be839','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('5668accf-afac-46a3-b097-177b74076fc9'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','54c9cc4e-0d46-4956-b92e-be9847f894de','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('0e8bd8d5-40fd-46fb-8228-5b66088681a2'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','b9739817-6408-4829-8719-1e26f8a9ceb3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('a22090b4-3ce6-448d-82b0-36592655d822'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','117da2f5-fff0-41e0-bba1-837124373098','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('d59c674a-eaf9-4158-8303-dbcb50a7230b'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','6ba0aeca-19f8-4247-a317-fffa81c5d5c1','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('450dad51-dcc9-4258-ba56-db39de6a8637'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','0c95581d-67de-48ae-a54b-a3748851d613','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('bf006fc0-8f33-4553-b567-a529af04eafe'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','45fce5ce-6a4c-4a6c-ab37-16ee0133628c','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('ad005c4b-dd71-4d42-99d8-95de7b1ed571'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','e6096350-9ac4-40aa-90c4-bbdff6e0b194','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('274356bc-8139-4e34-9332-ce7396f42c79'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('aa68a318-fe17-445c-ab53-0505fe48d0bb'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('882e7978-9754-4c8e-bb71-8fe4f4059503'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('8fc4571d-235b-4d4f-90e4-77e7ad9250d5'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('836606ce-894e-4765-bba5-b696cb5fe8cc'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + +-- inserting params for POEFSC +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('a57c01b1-cb1c-40f7-87e0-99d1dfd69902'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','adeb57e5-6b1c-4c0f-b5c9-9e57e600303f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('8f49b289-c1d0-438d-b9fc-3cb234167987'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','14a93209-370d-42f3-8ca2-479c953be839','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('46742d5d-dde9-4e3c-9e59-f2cf87ff016a'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','54c9cc4e-0d46-4956-b92e-be9847f894de','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('f6e178a9-5de3-4312-87c5-81d88ae0b45b'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','b9739817-6408-4829-8719-1e26f8a9ceb3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('34d4c1a3-b218-4083-93b5-cbbc57688594'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','117da2f5-fff0-41e0-bba1-837124373098','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('6b07db8d-9f7a-4d33-9a5f-7d98fc7038f1'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','6ba0aeca-19f8-4247-a317-fffa81c5d5c1','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('9d8cc94b-4d5f-4c62-b9db-b87bb0213b8d'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','0c95581d-67de-48ae-a54b-a3748851d613','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('d63a9079-c99b-4d92-864f-46cc9bb18388'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','45fce5ce-6a4c-4a6c-ab37-16ee0133628c','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('625970f9-7c93-4c3d-97fe-62f5a9d598f1'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','e6096350-9ac4-40aa-90c4-bbdff6e0b194','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('34fa9839-8289-473a-9095-c2b1159ef5d3'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('f747f231-66f5-4a52-bb71-8d7b5f618d23'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('0177f93a-15f6-41e5-a3ca-dc8f5bb727ab'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('cbf5b41f-2d89-4284-858f-d2cda7b060f7'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('ebed3001-93f1-49ba-a935-3d463b0d76fc'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + + +-- inserting params for ISLH +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('7e2e4b79-2f4c-451e-a28f-df1ad61c4f3b'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','164050e3-e35b-480d-bf6e-ed2fab86f370','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('adff4edb-1f78-45de-9269-29016d09d597'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','e6096350-9ac4-40aa-90c4-bbdff6e0b194','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('2239c77e-e073-47f3-aed7-e1edc6b8a9a4'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','45fce5ce-6a4c-4a6c-ab37-16ee0133628c','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('53ab68f9-8da7-48fa-80ac-bf91f05a4650'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','b9739817-6408-4829-8719-1e26f8a9ceb3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('e9d3bc63-bc4a-43d0-98f1-48e3e51d2307'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','0c95581d-67de-48ae-a54b-a3748851d613','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('6632cbad-3fa0-46b8-a1ac-0b2bb5123401'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('4ef58b87-8a93-44ec-b5c8-5b5779d8392e'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','599bbc21-8d1d-4039-9a89-ff52e3582144','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('d53e5f61-e92f-4ecb-9e1d-72ab8a99790f'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','a335e38a-7d95-4ba3-9c8b-75a5e00948bc','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('d94d2c5e-e91a-47d1-96b3-1c5d68a745dd'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','b03af5dc-7701-4e22-a986-d1889a2a8f27','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('7b8db256-e881-451e-a722-6431784e957f'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','add5114b-2a23-4e23-92b3-6dd0778dfc33','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('fedbd62d-d2fa-42b1-b6f6-c9c07e8c4014'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('c7a66e66-dabe-4f0b-a70d-f9639e87761a'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','2e091a7d-a1fd-4017-9f2d-73ad752a30c2','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('18f8b39f-37a5-4536-85d8-4b8b0a6bff94'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','739bbc23-cd08-4612-8e5d-da992202344e','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('7f20ed2e-1bdf-4370-b028-1251c07d3da1'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','95ee2e21-b232-4d74-9ec5-218564a8a8b9','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('a5be6b6f-e007-4d9f-8b1b-63e8ed5c4337'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','9de7fd2a-75c7-4c5c-ba5d-1a92f0b2f5f4','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('df5665d7-7b3d-487d-9d71-95d0e2832ae1'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('c08f7ab1-6c3c-4627-b22f-1e987ba6f4f2'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('4d9ed9b0-957d-4e6a-a3d4-5e2e2784ef62'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','14a93209-370d-42f3-8ca2-479c953be839','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('6acb30b9-65a0-4902-85ed-1acb6f4ac930'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','5335e243-ab5b-4906-b84f-bd8c35ba64b3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('fd83c2ba-0c59-4598-81d6-b56cc8d9979d'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + +-- inserting params fo IOSFSC +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('f61ab040-dab4-4505-906d-d9a3a5da3515'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','0c95581d-67de-48ae-a54b-a3748851d613','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('421053c8-7b4a-44fc-8c73-14b72755c1f7'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','117da2f5-fff0-41e0-bba1-837124373098','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('8f8a8783-0ca2-4f0f-961f-07d1e3cdbf64'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','14a93209-370d-42f3-8ca2-479c953be839','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('ab332c8f-f46e-4d49-b29a-6adf7e67f9c7'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('a6e24b83-9cb4-4e56-9e38-7bdbd9d5c5fe'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','84d86517-9b88-4520-8d67-5ba892b85d10','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('4e05a7c7-bd0a-4c94-a99b-f052a8812aef'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','54c9cc4e-0d46-4956-b92e-be9847f894de','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('8ec5cd5d-d249-42e9-b11d-76a243d4045f'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','6ba0aeca-19f8-4247-a317-fffa81c5d5c1','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('2b6b9d89-65f3-4291-9e44-48d18d2a4070'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('a3d3c08f-d2a3-4ad1-b85f-b1daee12d71c'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','adeb57e5-6b1c-4c0f-b5c9-9e57e600303f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('94d45661-82ac-479f-b7be-8e7a50ad46db'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('c897cfa3-9b06-47b5-8e12-522f0897e59a'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','b9739817-6408-4829-8719-1e26f8a9ceb3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('61832b60-2a2d-4e35-a799-b7ff9fa6a01e'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('46531d32-91a5-4d98-a206-d0f1e14e2ff4'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','cd6d6ddf-7104-4d24-a8d6-d37fed61defe','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('a1d4f95e-f28f-4b6a-b83f-8f328f2b2498'::uuid,'81e29d0c-02a6-4a7a-be02-554deb3ee49e','f9753611-4b3e-4bf5-8e00-6d9ce9900f50','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + + +-- inserting params fo IDSFSC +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('25d90d5b-c58f-45e7-8c60-e7f63a0535b6'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','0c95581d-67de-48ae-a54b-a3748851d613','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('8bb29da3-32e7-4e98-b241-63b8c8c81c3b'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','117da2f5-fff0-41e0-bba1-837124373098','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('b8c12287-dcf6-4f88-bf7b-f7e99283f23d'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','14a93209-370d-42f3-8ca2-479c953be839','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('3b9f3eab-8e18-4888-81f4-c442b4e951cf'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('7a8430f7-ff55-4a80-b174-e1d4a2f21f25'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','70eecf7f-beae-4906-95ba-cbfe6797cf3a','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('2eaf2e5b-254e-48f0-a2c5-98d04087293f'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','54c9cc4e-0d46-4956-b92e-be9847f894de','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('71f571c5-99a0-420a-b375-bb859e3488a2'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','6ba0aeca-19f8-4247-a317-fffa81c5d5c1','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('cce73f9e-e3db-4d7f-a908-d9985f1b3f27'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('46c559e5-9f49-4b7e-98b6-b9d8e2a4e2cf'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','adeb57e5-6b1c-4c0f-b5c9-9e57e600303f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('4512b905-cb68-4087-90b5-74e80ba9ec16'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('d9887f60-e930-4f95-b53e-e9f0d8a445d3'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','b9739817-6408-4829-8719-1e26f8a9ceb3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('f65b54fa-0e1c-45cc-b7f4-b41d356b970d'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), + ('ce36b6e0-bcbf-4e96-9c5e-bd93fe9084c9'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','cd6d6ddf-7104-4d24-a8d6-d37fed61defe','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('d9acb388-09a5-464b-bb50-bf418b25e96a'::uuid,'690a5fc1-0ea5-4554-8294-a367b5daefa9','f9753611-4b3e-4bf5-8e00-6d9ce9900f50','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + +-- inserting params fo IHPK +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('d9acb388-09a5-464b-bb50-bf418b25e96b'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('3c2297b0-1ec7-4261-a41d-37e58999258b'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','cd37b2a6-ac7d-4c93-a148-ca67f7f67cff','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + +-- inserting params fo IHUPK +INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES + ('d9acb388-09a5-464b-bb50-bf418b25e96c'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('c045524a-90ec-4116-80a1-e2edb5cdf38f'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','cd37b2a6-ac7d-4c93-a148-ca67f7f67cff','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); diff --git a/pkg/handlers/primeapi/allowed_payment_service_item_params.go b/pkg/handlers/primeapi/allowed_payment_service_item_params.go index cc40edc4ff8..809582a592a 100644 --- a/pkg/handlers/primeapi/allowed_payment_service_item_params.go +++ b/pkg/handlers/primeapi/allowed_payment_service_item_params.go @@ -67,6 +67,21 @@ var ( models.ReServiceCodeDOSFSC: { models.ServiceItemParamNameWeightBilled, }, + models.ReServiceCodeISLH: { + models.ServiceItemParamNameWeightBilled, + }, + models.ReServiceCodeIHPK: { + models.ServiceItemParamNameWeightBilled, + }, + models.ReServiceCodeIHUPK: { + models.ServiceItemParamNameWeightBilled, + }, + models.ReServiceCodePOEFSC: { + models.ServiceItemParamNameWeightBilled, + }, + models.ReServiceCodePODFSC: { + models.ServiceItemParamNameWeightBilled, + }, } ) diff --git a/pkg/handlers/primeapi/payment_request_test.go b/pkg/handlers/primeapi/payment_request_test.go index 768e10c0033..114f03aa49b 100644 --- a/pkg/handlers/primeapi/payment_request_test.go +++ b/pkg/handlers/primeapi/payment_request_test.go @@ -947,13 +947,6 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerInvalidMTOReferenceID( suite.IsType(&paymentrequestop.CreatePaymentRequestUnprocessableEntity{}, response) typedResponse := response.(*paymentrequestop.CreatePaymentRequestUnprocessableEntity) - // Validate outgoing payload - // TODO: Can't validate the response because of the issue noted below. Figure out a way to - // either alter the service or relax the swagger requirements. - // suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) - // CreatePaymentRequestCheck is returning apperror.InvalidCreateInputError without any validation errors - // so InvalidFields won't be added to the payload. - suite.Contains(*typedResponse.Payload.Detail, "has missing ReferenceID") }) @@ -1013,13 +1006,6 @@ func (suite *HandlerSuite) TestCreatePaymentRequestHandlerInvalidMTOReferenceID( suite.IsType(&paymentrequestop.CreatePaymentRequestUnprocessableEntity{}, response) typedResponse := response.(*paymentrequestop.CreatePaymentRequestUnprocessableEntity) - // Validate outgoing payload - // TODO: Can't validate the response because of the issue noted below. Figure out a way to - // either alter the service or relax the swagger requirements. - // suite.NoError(typedResponse.Payload.Validate(strfmt.Default)) - // CreatePaymentRequestCheck is returning apperror.InvalidCreateInputError without any validation errors - // so InvalidFields won't be added to the payload. - suite.Contains(*typedResponse.Payload.Detail, "has missing ReferenceID") }) } diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 5d17e0388ce..9bee5c8f59f 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -232,3 +232,35 @@ type DomesticOriginSITFuelSurchargePricer interface { ) ParamsPricer } + +// IntlShippingAndLinehaulPricer prices international shipping and linehaul for a move +// +//go:generate mockery --name IntlShippingAndLinehaulPricer +type IntlShippingAndLinehaulPricer interface { + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string, isPPM bool) (unit.Cents, PricingDisplayParams, error) + ParamsPricer +} + +// IntlHHGPackPricer prices international packing for an HHG shipment within a move +// +//go:generate mockery --name IntlHHGPackPricer +type IntlHHGPackPricer interface { + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, servicesScheduleOrigin int, isPPM bool) (unit.Cents, PricingDisplayParams, error) + ParamsPricer +} + +// IntlHHGUnpackPricer prices international unpacking for an HHG shipment within a move +// +//go:generate mockery --name IntlHHGUnpackPricer +type IntlHHGUnpackPricer interface { + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, servicesScheduleDest int, isPPM bool) (unit.Cents, PricingDisplayParams, error) + ParamsPricer +} + +// IntlPortFuelSurchargePricer prices the POEFSC/PODFSC service items on a shipment within a move +// +//go:generate mockery --name IntlPortFuelSurchargePricer +type IntlPortFuelSurchargePricer interface { + Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, isPPM bool) (unit.Cents, PricingDisplayParams, error) + ParamsPricer +} diff --git a/pkg/services/ghcrateengine/fuel_surcharge_pricer.go b/pkg/services/ghcrateengine/fuel_surcharge_pricer.go index 7371a7f397f..72b71bafce6 100644 --- a/pkg/services/ghcrateengine/fuel_surcharge_pricer.go +++ b/pkg/services/ghcrateengine/fuel_surcharge_pricer.go @@ -27,7 +27,7 @@ func NewFuelSurchargePricer() services.FuelSurchargePricer { return &fuelSurchargePricer{} } -// Price determines the price for a counseling service +// Price determines the price for fuel surcharge func (p fuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { // Validate parameters if actualPickupDate.IsZero() { diff --git a/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go b/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go new file mode 100644 index 00000000000..9318f930e10 --- /dev/null +++ b/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go @@ -0,0 +1,56 @@ +package ghcrateengine + +import ( + "time" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/unit" +) + +type intlHHGPackPricer struct { +} + +// NewDomesticPackPricer creates a new pricer for the domestic pack service +func NewIntlHHGPackPricer() services.IntlHHGPackPricer { + return &intlHHGPackPricer{} +} + +// Price determines the price for a domestic pack service +func (p intlHHGPackPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, weight unit.Pound, servicesScheduleOrigin int, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { + return priceIntlPackUnpack(appCtx, models.ReServiceCodeIHPK, contractCode, referenceDate, weight, servicesScheduleOrigin, isPPM) +} + +// PriceUsingParams determines the price for a domestic pack service given PaymentServiceItemParams +func (p intlHHGPackPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) + if err != nil { + return unit.Cents(0), nil, err + } + + referenceDate, err := getParamTime(params, models.ServiceItemParamNameReferenceDate) + if err != nil { + return unit.Cents(0), nil, err + } + + servicesScheduleOrigin, err := getParamInt(params, models.ServiceItemParamNameServicesScheduleOrigin) + if err != nil { + return unit.Cents(0), nil, err + } + + weightBilled, err := getParamInt(params, models.ServiceItemParamNameWeightBilled) + if err != nil { + return unit.Cents(0), nil, err + } + + var isPPM = false + if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { + // PPMs do not require minimums for a shipment's weight + // this flag is passed into the Price function to ensure the weight min + // are not enforced for PPMs + isPPM = true + } + + return p.Price(appCtx, contractCode, referenceDate, unit.Pound(weightBilled), servicesScheduleOrigin, isPPM) +} diff --git a/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go b/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go new file mode 100644 index 00000000000..47e428f1e6d --- /dev/null +++ b/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go @@ -0,0 +1,56 @@ +package ghcrateengine + +import ( + "time" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/unit" +) + +type intlHHGUnpackPricer struct { +} + +// NewDomesticUnpackPricer creates a new pricer for the domestic unpack service +func NewIntlHHGUnpackPricer() services.IntlHHGUnpackPricer { + return &intlHHGUnpackPricer{} +} + +// Price determines the price for a domestic unpack service +func (p intlHHGUnpackPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, weight unit.Pound, servicesScheduleDest int, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { + return priceDomesticPackUnpack(appCtx, models.ReServiceCodeDUPK, contractCode, referenceDate, weight, servicesScheduleDest, isPPM) +} + +// PriceUsingParams determines the price for a domestic unpack service given PaymentServiceItemParams +func (p intlHHGUnpackPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) + if err != nil { + return unit.Cents(0), nil, err + } + + referenceDate, err := getParamTime(params, models.ServiceItemParamNameReferenceDate) + if err != nil { + return unit.Cents(0), nil, err + } + + servicesScheduleDest, err := getParamInt(params, models.ServiceItemParamNameServicesScheduleDest) + if err != nil { + return unit.Cents(0), nil, err + } + + weightBilled, err := getParamInt(params, models.ServiceItemParamNameWeightBilled) + if err != nil { + return unit.Cents(0), nil, err + } + + var isPPM = false + if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { + // PPMs do not require minimums for a shipment's weight + // this flag is passed into the Price function to ensure the weight min + // are not enforced for PPMs + isPPM = true + } + + return p.Price(appCtx, contractCode, referenceDate, unit.Pound(weightBilled), servicesScheduleDest, isPPM) +} diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go new file mode 100644 index 00000000000..0acac1eaffa --- /dev/null +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go @@ -0,0 +1,111 @@ +package ghcrateengine + +import ( + "database/sql" + "fmt" + "math" + "time" + + "github.com/gofrs/uuid" + "github.com/pkg/errors" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/apperror" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/unit" +) + +// FuelSurchargePricer is a service object to price domestic shorthaul +type portFuelSurchargePricer struct { +} + +// NewFuelSurchargePricer is the public constructor for a domesticFuelSurchargePricer using Pop +func NewPortFuelSurchargePricer() services.IntlPortFuelSurchargePricer { + return &portFuelSurchargePricer{} +} + +// Price determines the price for fuel surcharge +func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { + // Validate parameters + if actualPickupDate.IsZero() { + return 0, nil, errors.New("ActualPickupDate is required") + } + if distance <= 0 { + return 0, nil, errors.New("Distance must be greater than 0") + } + if !isPPM && weight < minIntlWeightHHG { + return 0, nil, fmt.Errorf("weight must be a minimum of %d", minIntlWeightHHG) + } + if fscWeightBasedDistanceMultiplier == 0 { + return 0, nil, errors.New("WeightBasedDistanceMultiplier is required") + } + if eiaFuelPrice == 0 { + return 0, nil, errors.New("EIAFuelPrice is required") + } + + fscPriceDifferenceInCents := (eiaFuelPrice - baseGHCDieselFuelPrice).Float64() / 1000.0 + fscMultiplier := fscWeightBasedDistanceMultiplier * distance.Float64() + fscPrice := fscMultiplier * fscPriceDifferenceInCents * 100 + totalCost := unit.Cents(math.Round(fscPrice)) + + displayParams := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameFSCPriceDifferenceInCents, Value: FormatFloat(fscPriceDifferenceInCents, 1)}, + {Key: models.ServiceItemParamNameFSCMultiplier, Value: FormatFloat(fscMultiplier, 7)}, + } + + return totalCost, displayParams, nil +} + +func (p portFuelSurchargePricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + actualPickupDate, err := getParamTime(params, models.ServiceItemParamNameActualPickupDate) + if err != nil { + return unit.Cents(0), nil, err + } + + var paymentServiceItem models.PaymentServiceItem + mtoShipment := params[0].PaymentServiceItem.MTOServiceItem.MTOShipment + + if mtoShipment.ID == uuid.Nil { + err = appCtx.DB().Eager("MTOServiceItem", "MTOServiceItem.MTOShipment").Find(&paymentServiceItem, params[0].PaymentServiceItemID) + if err != nil { + switch err { + case sql.ErrNoRows: + return unit.Cents(0), nil, apperror.NewNotFoundError(params[0].PaymentServiceItemID, "looking for PaymentServiceItem") + default: + return unit.Cents(0), nil, apperror.NewQueryError("PaymentServiceItem", err, "") + } + } + mtoShipment = paymentServiceItem.MTOServiceItem.MTOShipment + } + + distance, err := getParamInt(params, models.ServiceItemParamNameDistanceZip) + if err != nil { + return unit.Cents(0), nil, err + } + + weightBilled, err := getParamInt(params, models.ServiceItemParamNameWeightBilled) + if err != nil { + return unit.Cents(0), nil, err + } + + fscWeightBasedDistanceMultiplier, err := getParamFloat(params, models.ServiceItemParamNameFSCWeightBasedDistanceMultiplier) + if err != nil { + return unit.Cents(0), nil, err + } + + eiaFuelPrice, err := getParamInt(params, models.ServiceItemParamNameEIAFuelPrice) + if err != nil { + return unit.Cents(0), nil, err + } + + var isPPM = false + if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { + // PPMs do not require minimums for a shipment's weight + // this flag is passed into the Price function to ensure the weight min + // are not enforced for PPMs + isPPM = true + } + + return p.Price(appCtx, actualPickupDate, unit.Miles(distance), unit.Pound(weightBilled), fscWeightBasedDistanceMultiplier, unit.Millicents(eiaFuelPrice), isPPM) +} diff --git a/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go new file mode 100644 index 00000000000..2fec86a9b57 --- /dev/null +++ b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go @@ -0,0 +1,137 @@ +package ghcrateengine + +import ( + "fmt" + "math" + "time" + + "github.com/pkg/errors" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/unit" +) + +type intlShippingAndLinehaulPricer struct { +} + +// NewDomesticLinehaulPricer creates a new pricer for domestic linehaul services +func NewIntlShippingAndLinehaulPricer() services.DomesticLinehaulPricer { + return &intlShippingAndLinehaulPricer{} +} + +// Price determines the price for a domestic linehaul +func (p intlShippingAndLinehaulPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { + // Validate parameters + if len(contractCode) == 0 { + return 0, nil, errors.New("ContractCode is required") + } + if referenceDate.IsZero() { + return 0, nil, errors.New("ReferenceDate is required") + } + if !isPPM && weight < dlhPricerMinimumWeight { + return 0, nil, fmt.Errorf("Weight must be at least %d", dlhPricerMinimumWeight) + } + if len(serviceArea) == 0 { + return 0, nil, errors.New("ServiceArea is required") + } + + isPeakPeriod := IsPeakPeriod(referenceDate) + finalWeight := weight + + if isPPM && weight < dlhPricerMinimumWeight { + finalWeight = dlhPricerMinimumWeight + } + + domesticLinehaulPrice, err := fetchDomesticLinehaulPrice(appCtx, contractCode, isPeakPeriod, distance, finalWeight, serviceArea) + if err != nil { + return unit.Cents(0), nil, fmt.Errorf("could not fetch domestic linehaul rate: %w", err) + } + + basePrice := domesticLinehaulPrice.PriceMillicents.Float64() / 1000 + escalatedPrice, contractYear, err := escalatePriceForContractYear( + appCtx, + domesticLinehaulPrice.ContractID, + referenceDate, + true, + basePrice) + if err != nil { + return 0, nil, fmt.Errorf("could not calculate escalated price: %w", err) + } + + totalPrice := finalWeight.ToCWTFloat64() * distance.Float64() * escalatedPrice + totalPriceCents := unit.Cents(math.Round(totalPrice)) + + params := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameContractYearName, Value: contractYear.Name}, + {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(contractYear.EscalationCompounded)}, + {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(isPeakPeriod)}, + {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatFloat(domesticLinehaulPrice.PriceMillicents.ToDollarFloatNoRound(), 3)}, + } + + if isPPM && weight < dlhPricerMinimumWeight { + weightFactor := float64(weight) / float64(dlhPricerMinimumWeight) + cost := float64(weightFactor) * float64(totalPriceCents) + return unit.Cents(cost), params, nil + } + + return totalPriceCents, params, nil +} + +// PriceUsingParams determines the price for a domestic linehaul given PaymentServiceItemParams +func (p intlShippingAndLinehaulPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) + if err != nil { + return unit.Cents(0), nil, err + } + + distance, err := getParamInt(params, models.ServiceItemParamNameDistanceZip) + if err != nil { + return unit.Cents(0), nil, err + } + + referenceDate, err := getParamTime(params, models.ServiceItemParamNameReferenceDate) + if err != nil { + return unit.Cents(0), nil, err + } + + serviceAreaOrigin, err := getParamString(params, models.ServiceItemParamNameServiceAreaOrigin) + if err != nil { + return unit.Cents(0), nil, err + } + + weightBilled, err := getParamInt(params, models.ServiceItemParamNameWeightBilled) + if err != nil { + return unit.Cents(0), nil, err + } + + var isPPM = false + if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { + // PPMs do not require minimums for a shipment's weight or distance + // this flag is passed into the Price function to ensure the weight and distance mins + // are not enforced for PPMs + isPPM = true + } + + return p.Price(appCtx, contractCode, referenceDate, unit.Miles(distance), unit.Pound(weightBilled), serviceAreaOrigin, isPPM) +} + +// func fetchDomesticLinehaulPrice(appCtx appcontext.AppContext, contractCode string, isPeakPeriod bool, distance unit.Miles, weight unit.Pound, serviceArea string) (models.ReDomesticLinehaulPrice, error) { +// var domesticLinehaulPrice models.ReDomesticLinehaulPrice +// err := appCtx.DB().Q(). +// Join("re_domestic_service_areas sa", "domestic_service_area_id = sa.id"). +// Join("re_contracts c", "re_domestic_linehaul_prices.contract_id = c.id"). +// Where("c.code = $1", contractCode). +// Where("re_domestic_linehaul_prices.is_peak_period = $2", isPeakPeriod). +// Where("$3 between weight_lower and weight_upper", weight). +// Where("$4 between miles_lower and miles_upper", distance). +// Where("sa.service_area = $5", serviceArea). +// First(&domesticLinehaulPrice) + +// if err != nil { +// return models.ReDomesticLinehaulPrice{}, err +// } + +// return domesticLinehaulPrice, nil +// } diff --git a/pkg/services/ghcrateengine/pricer_helpers_intl.go b/pkg/services/ghcrateengine/pricer_helpers_intl.go new file mode 100644 index 00000000000..9f88b2d4ef1 --- /dev/null +++ b/pkg/services/ghcrateengine/pricer_helpers_intl.go @@ -0,0 +1,86 @@ +package ghcrateengine + +import ( + "fmt" + "math" + "time" + + "github.com/pkg/errors" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/unit" +) + +func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReServiceCode, contractCode string, referenceDate time.Time, weight unit.Pound, servicesSchedule int, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { + // Validate parameters + var intlOtherPriceCode models.ReServiceCode + switch packUnpackCode { + case models.ReServiceCodeIHPK: + intlOtherPriceCode = models.ReServiceCodeIHPK + case models.ReServiceCodeIHUPK: + intlOtherPriceCode = models.ReServiceCodeIHUPK + default: + return 0, nil, fmt.Errorf("unsupported pack/unpack code of %s", packUnpackCode) + } + if len(contractCode) == 0 { + return 0, nil, errors.New("ContractCode is required") + } + if referenceDate.IsZero() { + return 0, nil, errors.New("ReferenceDate is required") + } + if !isPPM && weight < minDomesticWeight { + return 0, nil, fmt.Errorf("Weight must be a minimum of %d", minDomesticWeight) + } + if servicesSchedule == 0 { + return 0, nil, errors.New("Services schedule is required") + } + + isPeakPeriod := IsPeakPeriod(referenceDate) + + intlOtherPrice, err := fetchIntlOtherPrice(appCtx, contractCode, intlOtherPriceCode, servicesSchedule, isPeakPeriod) + if err != nil { + return 0, nil, fmt.Errorf("could not lookup domestic other price: %w", err) + } + + finalWeight := weight + if isPPM && weight < minDomesticWeight { + finalWeight = minDomesticWeight + } + + basePrice := intlOtherPrice.PerUnitCents.Float64() + escalatedPrice, contractYear, err := escalatePriceForContractYear(appCtx, intlOtherPrice.ContractID, referenceDate, false, basePrice) + if err != nil { + return 0, nil, fmt.Errorf("could not calculate escalated price: %w", err) + } + + escalatedPrice = escalatedPrice * finalWeight.ToCWTFloat64() + + displayParams := services.PricingDisplayParams{ + { + Key: models.ServiceItemParamNameContractYearName, + Value: contractYear.Name, + }, + { + Key: models.ServiceItemParamNamePriceRateOrFactor, + Value: FormatCents(intlOtherPrice.PerUnitCents), + }, + { + Key: models.ServiceItemParamNameIsPeak, + Value: FormatBool(isPeakPeriod), + }, + { + Key: models.ServiceItemParamNameEscalationCompounded, + Value: FormatEscalation(contractYear.EscalationCompounded), + }, + } + + totalCost := unit.Cents(math.Round(escalatedPrice)) + if isPPM && weight < minDomesticWeight { + weightFactor := float64(weight) / float64(minDomesticWeight) + cost := float64(weightFactor) * float64(totalCost) + return unit.Cents(cost), displayParams, nil + } + return totalCost, displayParams, nil +} diff --git a/pkg/services/ghcrateengine/pricer_query_helpers.go b/pkg/services/ghcrateengine/pricer_query_helpers.go index 5fc88dd7d5e..05c7bf668df 100644 --- a/pkg/services/ghcrateengine/pricer_query_helpers.go +++ b/pkg/services/ghcrateengine/pricer_query_helpers.go @@ -45,6 +45,24 @@ func fetchDomOtherPrice(appCtx appcontext.AppContext, contractCode string, servi return domOtherPrice, nil } +func fetchIntlOtherPrice(appCtx appcontext.AppContext, contractCode string, serviceCode models.ReServiceCode, schedule int, isPeakPeriod bool) (models.ReIntlOtherPrice, error) { + var intlOtherPrice models.ReIntlOtherPrice + err := appCtx.DB().Q(). + Join("re_services", "service_id = re_services.id"). + Join("re_contracts", "re_contracts.id = re_intl_other_prices.contract_id"). + Where("re_contracts.code = $1", contractCode). + Where("re_services.code = $2", serviceCode). + Where("schedule = $3", schedule). + Where("is_peak_period = $4", isPeakPeriod). + First(&intlOtherPrice) + + if err != nil { + return models.ReIntlOtherPrice{}, err + } + + return intlOtherPrice, nil +} + func fetchDomServiceAreaPrice(appCtx appcontext.AppContext, contractCode string, serviceCode models.ReServiceCode, serviceArea string, isPeakPeriod bool) (models.ReDomesticServiceAreaPrice, error) { var domServiceAreaPrice models.ReDomesticServiceAreaPrice err := appCtx.DB().Q(). diff --git a/pkg/services/ghcrateengine/service_item_pricer.go b/pkg/services/ghcrateengine/service_item_pricer.go index 81ad0a42cf5..ecaf9b8139b 100644 --- a/pkg/services/ghcrateengine/service_item_pricer.go +++ b/pkg/services/ghcrateengine/service_item_pricer.go @@ -94,6 +94,16 @@ func PricerForServiceItem(serviceCode models.ReServiceCode) (services.ParamsPric return NewDomesticOriginSITPickupPricer(), nil case models.ReServiceCodeDDDSIT: return NewDomesticDestinationSITDeliveryPricer(), nil + case models.ReServiceCodeISLH: + return NewIntlShippingAndLinehaulPricer(), nil + case models.ReServiceCodeIHPK: + return NewIntlHHGPackPricer(), nil + case models.ReServiceCodeIHUPK: + return NewIntlHHGUnpackPricer(), nil + case models.ReServiceCodePOEFSC: + return NewPortFuelSurchargePricer(), nil + case models.ReServiceCodePODFSC: + return NewPortFuelSurchargePricer(), nil default: // TODO: We may want a different error type here after all pricers have been implemented return nil, apperror.NewNotImplementedError(fmt.Sprintf("pricer not found for code %s", serviceCode)) diff --git a/pkg/services/ghcrateengine/shared.go b/pkg/services/ghcrateengine/shared.go index 3f89a29cb40..171d8668bb1 100644 --- a/pkg/services/ghcrateengine/shared.go +++ b/pkg/services/ghcrateengine/shared.go @@ -9,6 +9,9 @@ import ( // minDomesticWeight is the minimum weight used in domestic calculations (weights below this are upgraded to the min) const minDomesticWeight = unit.Pound(500) +// minIntlWeightHHG is the minimum weight used in intl calculations (weights below this are upgraded to the min) +const minIntlWeightHHG = unit.Pound(500) + // dateInYear represents a specific date in a year (without caring what year it is) type dateInYear struct { month time.Month diff --git a/pkg/services/payment_request/payment_request_creator.go b/pkg/services/payment_request/payment_request_creator.go index 0b301193287..63b1f0950a7 100644 --- a/pkg/services/payment_request/payment_request_creator.go +++ b/pkg/services/payment_request/payment_request_creator.go @@ -402,7 +402,6 @@ func (p *paymentRequestCreator) createPaymentServiceItem(appCtx appcontext.AppCo paymentServiceItem.PaymentRequestID = paymentRequest.ID paymentServiceItem.PaymentRequest = *paymentRequest paymentServiceItem.Status = models.PaymentServiceItemStatusRequested - // No pricing at this point, so skipping the PriceCents field. paymentServiceItem.RequestedAt = requestedAt verrs, err := appCtx.DB().ValidateAndCreate(&paymentServiceItem) From 834cd2b2063dc0615501dbda34b215781e66ee41 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 17:08:33 +0000 Subject: [PATCH 35/52] pack and unpack done, need tests --- ...aram_values_to_service_params_table.up.sql | 20 ++++-- pkg/models/re_rate_area.go | 17 +++++ pkg/models/service_item_param_key.go | 8 +++ .../per_unit_cents_lookup.go | 63 +++++++++++++++++++ .../port_name_lookup.go | 34 ++++++++++ .../service_param_value_lookups.go | 13 ++++ pkg/services/ghc_rate_engine.go | 4 +- .../ghcrateengine/intl_hhg_pack_pricer.go | 19 ++---- .../ghcrateengine/intl_hhg_unpack_pricer.go | 19 ++---- .../ghcrateengine/pricer_helpers_intl.go | 39 +++--------- .../ghcrateengine/pricer_query_helpers.go | 28 +++------ .../CreatePaymentRequestForm.jsx | 4 +- 12 files changed, 180 insertions(+), 88 deletions(-) create mode 100644 pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go create mode 100644 pkg/payment_request/service_param_value_lookups/port_name_lookup.go diff --git a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql index 26ccf6dff90..14dc1422582 100644 --- a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql +++ b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql @@ -1,3 +1,7 @@ +-- need to add in param keys for international shipments, this will be used to show breakdowns to the TIO +INSERT INTO service_item_param_keys (id, key,description,type,origin,created_at,updated_at) VALUES + ('d9ad3878-4b94-4722-bbaf-d4b8080f339d','PortName','Name of the port for an international shipment','STRING','PRICER','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'), + ('597bb77e-0ce7-4ba2-9624-24300962625f','PerUnitCents','Per unit cents for a service item','INTEGER','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'); -- inserting params for PODFSC INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES @@ -14,7 +18,8 @@ INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,u ('aa68a318-fe17-445c-ab53-0505fe48d0bb'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), ('882e7978-9754-4c8e-bb71-8fe4f4059503'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), ('8fc4571d-235b-4d4f-90e4-77e7ad9250d5'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), - ('836606ce-894e-4765-bba5-b696cb5fe8cc'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + ('836606ce-894e-4765-bba5-b696cb5fe8cc'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('08701fa6-6352-4808-88b6-1fe103068f29'::uuid,'388115e8-abe9-441d-96cf-a39f24baa0a3','d9ad3878-4b94-4722-bbaf-d4b8080f339d','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); -- inserting params for POEFSC INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES @@ -31,7 +36,8 @@ INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,u ('f747f231-66f5-4a52-bb71-8d7b5f618d23'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','b79978a7-21b7-4656-af83-25585acffb20','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), ('0177f93a-15f6-41e5-a3ca-dc8f5bb727ab'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','d87d82da-3ac2-44e8-bce0-cb4de40f9a72','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), ('cbf5b41f-2d89-4284-858f-d2cda7b060f7'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), - ('ebed3001-93f1-49ba-a935-3d463b0d76fc'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + ('ebed3001-93f1-49ba-a935-3d463b0d76fc'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('aa7c3492-be44-46dd-983e-478623edc0be'::uuid,'f75758d8-2fcd-40ba-9432-3ff3032a71d1','d9ad3878-4b94-4722-bbaf-d4b8080f339d','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); -- inserting params for ISLH @@ -94,10 +100,12 @@ INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,u -- inserting params fo IHPK INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES - ('d9acb388-09a5-464b-bb50-bf418b25e96b'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), - ('3c2297b0-1ec7-4261-a41d-37e58999258b'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','cd37b2a6-ac7d-4c93-a148-ca67f7f67cff','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + ('d9acb388-09a5-464b-bb50-bf418b25e96b'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), -- ContractCode + ('0b31db7a-fbab-4e49-8526-00458ac3900c'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','597bb77e-0ce7-4ba2-9624-24300962625f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), -- PerUnitCents + ('9b0a74e3-afc4-4f42-8eb3-828f80fbfaf0'::uuid,'67ba1eaf-6ffd-49de-9a69-497be7789877','95ee2e21-b232-4d74-9ec5-218564a8a8b9','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); -- IsPeak -- inserting params fo IHUPK INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES - ('d9acb388-09a5-464b-bb50-bf418b25e96c'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), - ('c045524a-90ec-4116-80a1-e2edb5cdf38f'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','cd37b2a6-ac7d-4c93-a148-ca67f7f67cff','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + ('cb110853-6b1d-452b-9607-345721a70313'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','a1d31d35-c87d-4a7d-b0b8-8b2646b96e43','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), -- ContractCode + ('cc95d5df-1167-4fe9-8682-07f8fbe7c286'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','597bb77e-0ce7-4ba2-9624-24300962625f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), -- PerUnitCents + ('759bd482-b2f6-461b-a898-792415efa5f1'::uuid,'56e91c2d-015d-4243-9657-3ed34867abaa','95ee2e21-b232-4d74-9ec5-218564a8a8b9','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); -- IsPeak diff --git a/pkg/models/re_rate_area.go b/pkg/models/re_rate_area.go index 167b70577ce..a2b2a274761 100644 --- a/pkg/models/re_rate_area.go +++ b/pkg/models/re_rate_area.go @@ -1,6 +1,7 @@ package models import ( + "fmt" "time" "github.com/gobuffalo/pop/v6" @@ -53,3 +54,19 @@ func FetchReRateAreaItem(tx *pop.Connection, contractID uuid.UUID, code string) return &area, err } + +// a db stored proc that takes in an address id & a service code to get the rate area id for an address +func FetchRateAreaID(db *pop.Connection, addressID uuid.UUID, serviceID uuid.UUID) (uuid.UUID, error) { + if addressID != uuid.Nil && serviceID != uuid.Nil { + var rateAreaID uuid.UUID + err := db.RawQuery("SELECT get_rate_area_id($1, $2)", addressID, serviceID). + First(&rateAreaID) + + if err != nil { + return uuid.Nil, fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", addressID, serviceID, err) + } + return rateAreaID, nil + } + // Return error if required parameters are not provided + return uuid.Nil, fmt.Errorf("error fetching rate area ID - required parameters not provided") +} diff --git a/pkg/models/service_item_param_key.go b/pkg/models/service_item_param_key.go index 3bfd789dcc4..868c6785b55 100644 --- a/pkg/models/service_item_param_key.go +++ b/pkg/models/service_item_param_key.go @@ -61,6 +61,10 @@ const ( ServiceItemParamNameNTSPackingFactor ServiceItemParamName = "NTSPackingFactor" // ServiceItemParamNameNumberDaysSIT is the param key name NumberDaysSIT ServiceItemParamNameNumberDaysSIT ServiceItemParamName = "NumberDaysSIT" + // ServiceItemParamNamePerUnitCents is the param key name PerUnitCents + ServiceItemParamNamePerUnitCents ServiceItemParamName = "PerUnitCents" + // ServiceItemParamNamePortName is the param key name PortName + ServiceItemParamNamePortName ServiceItemParamName = "PortName" // ServiceItemParamNamePriceAreaDest is the param key name PriceAreaDest ServiceItemParamNamePriceAreaDest ServiceItemParamName = "PriceAreaDest" // ServiceItemParamNamePriceAreaIntlDest is the param key name PriceAreaIntlDest @@ -275,6 +279,8 @@ var ValidServiceItemParamNames = []ServiceItemParamName{ ServiceItemParamNameStandaloneCrateCap, ServiceItemParamNameUncappedRequestTotal, ServiceItemParamNameLockedPriceCents, + ServiceItemParamNamePerUnitCents, + ServiceItemParamNamePortName, } // ValidServiceItemParamNameStrings lists all valid service item param key names @@ -349,6 +355,8 @@ var ValidServiceItemParamNameStrings = []string{ string(ServiceItemParamNameStandaloneCrateCap), string(ServiceItemParamNameUncappedRequestTotal), string(ServiceItemParamNameLockedPriceCents), + string(ServiceItemParamNamePerUnitCents), + string(ServiceItemParamNamePortName), } // ValidServiceItemParamTypes lists all valid service item param types diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go new file mode 100644 index 00000000000..07670b009fa --- /dev/null +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go @@ -0,0 +1,63 @@ +package serviceparamvaluelookups + +import ( + "database/sql" + "fmt" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services/ghcrateengine" +) + +// PerUnitCents does lookup on the per unit cents value associated with a service item +type PerUnitCentsLookup struct { + ServiceItem models.MTOServiceItem + MTOShipment models.MTOShipment +} + +func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemParamKeyData) (string, error) { + var isPeakPeriod bool + serviceID := p.ServiceItem.ReServiceID + contractID := s.ContractID + if p.ServiceItem.ReService.Code == models.ReServiceCodeIHPK { + // IHPK we need the rate area id for the pickup address + rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) + if err != nil { + return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + } + isPeakPeriod = ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) + var reIntlOtherPrice models.ReIntlOtherPrice + err = appCtx.DB().Q(). + Where("contract_id = ?", contractID). + Where("service_id = ?", serviceID). + Where("is_peak_period = ?", isPeakPeriod). + Where("rate_area_id = ?", rateAreaID). + First(&reIntlOtherPrice) + if err != nil { + return "", fmt.Errorf("error fetching IHPK per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, and rateAreaID: %s: %s", contractID, serviceID, isPeakPeriod, rateAreaID, err) + } + return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil + } + + if p.ServiceItem.ReService.Code == models.ReServiceCodeIHUPK { + // IHUPK we need the rate area id for the destination address + rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) + if err != nil && err != sql.ErrNoRows { + return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + } + isPeakPeriod = ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) + var reIntlOtherPrice models.ReIntlOtherPrice + err = appCtx.DB().Q(). + Where("contract_id = ?", contractID). + Where("service_id = ?", serviceID). + Where("is_peak_period = ?", isPeakPeriod). + Where("rate_area_id = ?", rateAreaID). + First(&reIntlOtherPrice) + if err != nil { + return "", fmt.Errorf("error fetching IHUPK per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, and rateAreaID: %s: %s", contractID, serviceID, isPeakPeriod, rateAreaID, err) + } + return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil + } else { + return "", fmt.Errorf("unsupported service code to retrieve service item param PerUnitCents") + } +} diff --git a/pkg/payment_request/service_param_value_lookups/port_name_lookup.go b/pkg/payment_request/service_param_value_lookups/port_name_lookup.go new file mode 100644 index 00000000000..5013d3ae2c8 --- /dev/null +++ b/pkg/payment_request/service_param_value_lookups/port_name_lookup.go @@ -0,0 +1,34 @@ +package serviceparamvaluelookups + +import ( + "fmt" + + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/models" +) + +// PortNameLookup does lookup on the shipment and finds the port name +type PortNameLookup struct { + ServiceItem models.MTOServiceItem +} + +func (p PortNameLookup) lookup(appCtx appcontext.AppContext, _ *ServiceItemParamKeyData) (string, error) { + var portLocationID *uuid.UUID + if p.ServiceItem.PODLocationID != nil { + portLocationID = p.ServiceItem.PODLocationID + } else if p.ServiceItem.POELocationID != nil { + portLocationID = p.ServiceItem.POELocationID + } else { + return "", nil + } + var portLocation models.PortLocation + err := appCtx.DB().Q(). + EagerPreload("Port"). + Where("id = $1", portLocationID).First(&portLocation) + if err != nil { + return "", fmt.Errorf("unable to find port location with id %s", portLocationID) + } + return portLocation.Port.PortName, nil +} diff --git a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go index 0bb499be70b..c3669e5cb41 100644 --- a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go +++ b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go @@ -21,6 +21,7 @@ type ServiceItemParamKeyData struct { MTOServiceItem models.MTOServiceItem PaymentRequestID uuid.UUID MoveTaskOrderID uuid.UUID + ContractID uuid.UUID ContractCode string mtoShipmentID *uuid.UUID paramCache *ServiceParamsCache @@ -85,6 +86,8 @@ var ServiceItemParamsWithLookups = []models.ServiceItemParamName{ models.ServiceItemParamNameStandaloneCrate, models.ServiceItemParamNameStandaloneCrateCap, models.ServiceItemParamNameLockedPriceCents, + models.ServiceItemParamNamePerUnitCents, + models.ServiceItemParamNamePortName, } // ServiceParamLookupInitialize initializes service parameter lookup @@ -120,6 +123,7 @@ func ServiceParamLookupInitialize( to this query. Otherwise the contract_code field could be added to the MTO. */ ContractCode: contract.Code, + ContractID: contract.ID, } // @@ -430,6 +434,15 @@ func InitializeLookups(appCtx appcontext.AppContext, shipment models.MTOShipment ServiceItem: serviceItem, } + lookups[models.ServiceItemParamNamePerUnitCents] = PerUnitCentsLookup{ + ServiceItem: serviceItem, + MTOShipment: shipment, + } + + lookups[models.ServiceItemParamNamePortName] = PortNameLookup{ + ServiceItem: serviceItem, + } + return lookups } diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 9bee5c8f59f..440d710f4b2 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -245,7 +245,7 @@ type IntlShippingAndLinehaulPricer interface { // //go:generate mockery --name IntlHHGPackPricer type IntlHHGPackPricer interface { - Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, servicesScheduleOrigin int, isPPM bool) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, PricingDisplayParams, error) ParamsPricer } @@ -253,7 +253,7 @@ type IntlHHGPackPricer interface { // //go:generate mockery --name IntlHHGUnpackPricer type IntlHHGUnpackPricer interface { - Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, servicesScheduleDest int, isPPM bool) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go b/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go index 9318f930e10..12090aa3bde 100644 --- a/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go +++ b/pkg/services/ghcrateengine/intl_hhg_pack_pricer.go @@ -12,17 +12,14 @@ import ( type intlHHGPackPricer struct { } -// NewDomesticPackPricer creates a new pricer for the domestic pack service func NewIntlHHGPackPricer() services.IntlHHGPackPricer { return &intlHHGPackPricer{} } -// Price determines the price for a domestic pack service -func (p intlHHGPackPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, weight unit.Pound, servicesScheduleOrigin int, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { - return priceIntlPackUnpack(appCtx, models.ReServiceCodeIHPK, contractCode, referenceDate, weight, servicesScheduleOrigin, isPPM) +func (p intlHHGPackPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { + return priceIntlPackUnpack(appCtx, models.ReServiceCodeIHPK, contractCode, referenceDate, weight, perUnitCents) } -// PriceUsingParams determines the price for a domestic pack service given PaymentServiceItemParams func (p intlHHGPackPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) if err != nil { @@ -34,7 +31,7 @@ func (p intlHHGPackPricer) PriceUsingParams(appCtx appcontext.AppContext, params return unit.Cents(0), nil, err } - servicesScheduleOrigin, err := getParamInt(params, models.ServiceItemParamNameServicesScheduleOrigin) + perUnitCents, err := getParamInt(params, models.ServiceItemParamNamePerUnitCents) if err != nil { return unit.Cents(0), nil, err } @@ -44,13 +41,5 @@ func (p intlHHGPackPricer) PriceUsingParams(appCtx appcontext.AppContext, params return unit.Cents(0), nil, err } - var isPPM = false - if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { - // PPMs do not require minimums for a shipment's weight - // this flag is passed into the Price function to ensure the weight min - // are not enforced for PPMs - isPPM = true - } - - return p.Price(appCtx, contractCode, referenceDate, unit.Pound(weightBilled), servicesScheduleOrigin, isPPM) + return p.Price(appCtx, contractCode, referenceDate, unit.Pound(weightBilled), perUnitCents) } diff --git a/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go b/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go index 47e428f1e6d..d4cb95dd315 100644 --- a/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go +++ b/pkg/services/ghcrateengine/intl_hhg_unpack_pricer.go @@ -12,17 +12,14 @@ import ( type intlHHGUnpackPricer struct { } -// NewDomesticUnpackPricer creates a new pricer for the domestic unpack service func NewIntlHHGUnpackPricer() services.IntlHHGUnpackPricer { return &intlHHGUnpackPricer{} } -// Price determines the price for a domestic unpack service -func (p intlHHGUnpackPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, weight unit.Pound, servicesScheduleDest int, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { - return priceDomesticPackUnpack(appCtx, models.ReServiceCodeDUPK, contractCode, referenceDate, weight, servicesScheduleDest, isPPM) +func (p intlHHGUnpackPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { + return priceIntlPackUnpack(appCtx, models.ReServiceCodeIHUPK, contractCode, referenceDate, weight, perUnitCents) } -// PriceUsingParams determines the price for a domestic unpack service given PaymentServiceItemParams func (p intlHHGUnpackPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) if err != nil { @@ -34,7 +31,7 @@ func (p intlHHGUnpackPricer) PriceUsingParams(appCtx appcontext.AppContext, para return unit.Cents(0), nil, err } - servicesScheduleDest, err := getParamInt(params, models.ServiceItemParamNameServicesScheduleDest) + perUnitCents, err := getParamInt(params, models.ServiceItemParamNamePerUnitCents) if err != nil { return unit.Cents(0), nil, err } @@ -44,13 +41,5 @@ func (p intlHHGUnpackPricer) PriceUsingParams(appCtx appcontext.AppContext, para return unit.Cents(0), nil, err } - var isPPM = false - if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { - // PPMs do not require minimums for a shipment's weight - // this flag is passed into the Price function to ensure the weight min - // are not enforced for PPMs - isPPM = true - } - - return p.Price(appCtx, contractCode, referenceDate, unit.Pound(weightBilled), servicesScheduleDest, isPPM) + return p.Price(appCtx, contractCode, referenceDate, unit.Pound(weightBilled), perUnitCents) } diff --git a/pkg/services/ghcrateengine/pricer_helpers_intl.go b/pkg/services/ghcrateengine/pricer_helpers_intl.go index 9f88b2d4ef1..73428847e51 100644 --- a/pkg/services/ghcrateengine/pricer_helpers_intl.go +++ b/pkg/services/ghcrateengine/pricer_helpers_intl.go @@ -13,15 +13,8 @@ import ( "github.com/transcom/mymove/pkg/unit" ) -func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReServiceCode, contractCode string, referenceDate time.Time, weight unit.Pound, servicesSchedule int, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { - // Validate parameters - var intlOtherPriceCode models.ReServiceCode - switch packUnpackCode { - case models.ReServiceCodeIHPK: - intlOtherPriceCode = models.ReServiceCodeIHPK - case models.ReServiceCodeIHUPK: - intlOtherPriceCode = models.ReServiceCodeIHUPK - default: +func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReServiceCode, contractCode string, referenceDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { + if packUnpackCode != models.ReServiceCodeIHPK && packUnpackCode != models.ReServiceCodeIHUPK { return 0, nil, fmt.Errorf("unsupported pack/unpack code of %s", packUnpackCode) } if len(contractCode) == 0 { @@ -30,32 +23,21 @@ func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReS if referenceDate.IsZero() { return 0, nil, errors.New("ReferenceDate is required") } - if !isPPM && weight < minDomesticWeight { - return 0, nil, fmt.Errorf("Weight must be a minimum of %d", minDomesticWeight) - } - if servicesSchedule == 0 { - return 0, nil, errors.New("Services schedule is required") - } isPeakPeriod := IsPeakPeriod(referenceDate) - intlOtherPrice, err := fetchIntlOtherPrice(appCtx, contractCode, intlOtherPriceCode, servicesSchedule, isPeakPeriod) + contract, err := fetchContractsByContractCode(appCtx, contractCode) if err != nil { - return 0, nil, fmt.Errorf("could not lookup domestic other price: %w", err) + return 0, nil, fmt.Errorf("could not find contract with code: %s: %w", contractCode, err) } - finalWeight := weight - if isPPM && weight < minDomesticWeight { - finalWeight = minDomesticWeight - } - - basePrice := intlOtherPrice.PerUnitCents.Float64() - escalatedPrice, contractYear, err := escalatePriceForContractYear(appCtx, intlOtherPrice.ContractID, referenceDate, false, basePrice) + basePrice := float64(perUnitCents) + escalatedPrice, contractYear, err := escalatePriceForContractYear(appCtx, contract.ID, referenceDate, false, basePrice) if err != nil { return 0, nil, fmt.Errorf("could not calculate escalated price: %w", err) } - escalatedPrice = escalatedPrice * finalWeight.ToCWTFloat64() + escalatedPrice = escalatedPrice * weight.ToCWTFloat64() displayParams := services.PricingDisplayParams{ { @@ -64,7 +46,7 @@ func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReS }, { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(intlOtherPrice.PerUnitCents), + Value: FormatCents(unit.Cents(perUnitCents)), }, { Key: models.ServiceItemParamNameIsPeak, @@ -77,10 +59,5 @@ func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReS } totalCost := unit.Cents(math.Round(escalatedPrice)) - if isPPM && weight < minDomesticWeight { - weightFactor := float64(weight) / float64(minDomesticWeight) - cost := float64(weightFactor) * float64(totalCost) - return unit.Cents(cost), displayParams, nil - } return totalCost, displayParams, nil } diff --git a/pkg/services/ghcrateengine/pricer_query_helpers.go b/pkg/services/ghcrateengine/pricer_query_helpers.go index 05c7bf668df..51acb06f9bd 100644 --- a/pkg/services/ghcrateengine/pricer_query_helpers.go +++ b/pkg/services/ghcrateengine/pricer_query_helpers.go @@ -45,24 +45,6 @@ func fetchDomOtherPrice(appCtx appcontext.AppContext, contractCode string, servi return domOtherPrice, nil } -func fetchIntlOtherPrice(appCtx appcontext.AppContext, contractCode string, serviceCode models.ReServiceCode, schedule int, isPeakPeriod bool) (models.ReIntlOtherPrice, error) { - var intlOtherPrice models.ReIntlOtherPrice - err := appCtx.DB().Q(). - Join("re_services", "service_id = re_services.id"). - Join("re_contracts", "re_contracts.id = re_intl_other_prices.contract_id"). - Where("re_contracts.code = $1", contractCode). - Where("re_services.code = $2", serviceCode). - Where("schedule = $3", schedule). - Where("is_peak_period = $4", isPeakPeriod). - First(&intlOtherPrice) - - if err != nil { - return models.ReIntlOtherPrice{}, err - } - - return intlOtherPrice, nil -} - func fetchDomServiceAreaPrice(appCtx appcontext.AppContext, contractCode string, serviceCode models.ReServiceCode, serviceArea string, isPeakPeriod bool) (models.ReDomesticServiceAreaPrice, error) { var domServiceAreaPrice models.ReDomesticServiceAreaPrice err := appCtx.DB().Q(). @@ -121,6 +103,16 @@ func fetchContractsByContractId(appCtx appcontext.AppContext, contractID uuid.UU return contracts, nil } +func fetchContractsByContractCode(appCtx appcontext.AppContext, contractCode string) (models.ReContract, error) { + var contract models.ReContract + err := appCtx.DB().Where("code = $1", contractCode).First(&contract) + if err != nil { + return models.ReContract{}, err + } + + return contract, nil +} + func fetchShipmentTypePrice(appCtx appcontext.AppContext, contractCode string, serviceCode models.ReServiceCode, market models.Market) (models.ReShipmentTypePrice, error) { var shipmentTypePrice models.ReShipmentTypePrice err := appCtx.DB().Q(). diff --git a/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx b/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx index 3a3edafb556..5aa3fdc0187 100644 --- a/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx +++ b/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx @@ -143,7 +143,9 @@ const CreatePaymentRequestForm = ({ mtoServiceItem.reServiceCode === 'DPK' || mtoServiceItem.reServiceCode === 'DDSFSC' || mtoServiceItem.reServiceCode === 'DOSFSC' || - mtoServiceItem.reServiceCode === 'DDSHUT') && ( + mtoServiceItem.reServiceCode === 'DDSHUT' || + mtoServiceItem.reServiceCode === 'IHPK' || + mtoServiceItem.reServiceCode === 'IHUPK') && ( Date: Thu, 2 Jan 2025 17:53:50 +0000 Subject: [PATCH 36/52] POEFSC and PODFSC should be good, onto linehaul, still need tests --- ...aram_values_to_service_params_table.up.sql | 2 +- pkg/models/re_rate_area.go | 1 - pkg/services/ghc_rate_engine.go | 2 +- .../intl_port_fuel_surcharge_pricer.go | 21 ++++++++----------- pkg/services/ghcrateengine/pricer_helpers.go | 4 ++-- .../ghcrateengine/service_item_pricer.go | 1 - 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql index 14dc1422582..eec414779d0 100644 --- a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql +++ b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql @@ -1,6 +1,6 @@ -- need to add in param keys for international shipments, this will be used to show breakdowns to the TIO INSERT INTO service_item_param_keys (id, key,description,type,origin,created_at,updated_at) VALUES - ('d9ad3878-4b94-4722-bbaf-d4b8080f339d','PortName','Name of the port for an international shipment','STRING','PRICER','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'), + ('d9ad3878-4b94-4722-bbaf-d4b8080f339d','PortName','Name of the port for an international shipment','STRING','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'), ('597bb77e-0ce7-4ba2-9624-24300962625f','PerUnitCents','Per unit cents for a service item','INTEGER','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'); -- inserting params for PODFSC diff --git a/pkg/models/re_rate_area.go b/pkg/models/re_rate_area.go index a2b2a274761..960f4258d8c 100644 --- a/pkg/models/re_rate_area.go +++ b/pkg/models/re_rate_area.go @@ -67,6 +67,5 @@ func FetchRateAreaID(db *pop.Connection, addressID uuid.UUID, serviceID uuid.UUI } return rateAreaID, nil } - // Return error if required parameters are not provided return uuid.Nil, fmt.Errorf("error fetching rate area ID - required parameters not provided") } diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 440d710f4b2..4a74692a5bb 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -261,6 +261,6 @@ type IntlHHGUnpackPricer interface { // //go:generate mockery --name IntlPortFuelSurchargePricer type IntlPortFuelSurchargePricer interface { - Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, isPPM bool) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, portName string) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go index 0acac1eaffa..7d2c94e7096 100644 --- a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go @@ -16,17 +16,14 @@ import ( "github.com/transcom/mymove/pkg/unit" ) -// FuelSurchargePricer is a service object to price domestic shorthaul type portFuelSurchargePricer struct { } -// NewFuelSurchargePricer is the public constructor for a domesticFuelSurchargePricer using Pop func NewPortFuelSurchargePricer() services.IntlPortFuelSurchargePricer { return &portFuelSurchargePricer{} } -// Price determines the price for fuel surcharge -func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { +func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, portName string) (unit.Cents, services.PricingDisplayParams, error) { // Validate parameters if actualPickupDate.IsZero() { return 0, nil, errors.New("ActualPickupDate is required") @@ -34,7 +31,7 @@ func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate if distance <= 0 { return 0, nil, errors.New("Distance must be greater than 0") } - if !isPPM && weight < minIntlWeightHHG { + if weight < minIntlWeightHHG { return 0, nil, fmt.Errorf("weight must be a minimum of %d", minIntlWeightHHG) } if fscWeightBasedDistanceMultiplier == 0 { @@ -43,6 +40,9 @@ func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate if eiaFuelPrice == 0 { return 0, nil, errors.New("EIAFuelPrice is required") } + if portName == "" { + return 0, nil, errors.New("PortName is required") + } fscPriceDifferenceInCents := (eiaFuelPrice - baseGHCDieselFuelPrice).Float64() / 1000.0 fscMultiplier := fscWeightBasedDistanceMultiplier * distance.Float64() @@ -99,13 +99,10 @@ func (p portFuelSurchargePricer) PriceUsingParams(appCtx appcontext.AppContext, return unit.Cents(0), nil, err } - var isPPM = false - if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { - // PPMs do not require minimums for a shipment's weight - // this flag is passed into the Price function to ensure the weight min - // are not enforced for PPMs - isPPM = true + portName, err := getParamString(params, models.ServiceItemParamNamePortName) + if err != nil { + return unit.Cents(0), nil, err } - return p.Price(appCtx, actualPickupDate, unit.Miles(distance), unit.Pound(weightBilled), fscWeightBasedDistanceMultiplier, unit.Millicents(eiaFuelPrice), isPPM) + return p.Price(appCtx, actualPickupDate, unit.Miles(distance), unit.Pound(weightBilled), fscWeightBasedDistanceMultiplier, unit.Millicents(eiaFuelPrice), portName) } diff --git a/pkg/services/ghcrateengine/pricer_helpers.go b/pkg/services/ghcrateengine/pricer_helpers.go index faa802afb0b..cb804b0da49 100644 --- a/pkg/services/ghcrateengine/pricer_helpers.go +++ b/pkg/services/ghcrateengine/pricer_helpers.go @@ -448,10 +448,10 @@ func createPricerGeneratedParams(appCtx appcontext.AppContext, paymentServiceIte Where("key = ?", param.Key). First(&serviceItemParamKey) if err != nil { - return paymentServiceItemParams, fmt.Errorf("Unable to find service item param key for %v", param.Key) + return paymentServiceItemParams, fmt.Errorf("unable to find service item param key for %v", param.Key) } if serviceItemParamKey.Origin != models.ServiceItemParamOriginPricer { - return paymentServiceItemParams, fmt.Errorf("Service item param key is not a pricer param. Param key: %v", serviceItemParamKey.Key) + return paymentServiceItemParams, fmt.Errorf("service item param key is not a pricer param. Param key: %v", serviceItemParamKey.Key) } // Create the PaymentServiceItemParam from the PricingDisplayParam and store it in the DB diff --git a/pkg/services/ghcrateengine/service_item_pricer.go b/pkg/services/ghcrateengine/service_item_pricer.go index ecaf9b8139b..a673f832b63 100644 --- a/pkg/services/ghcrateengine/service_item_pricer.go +++ b/pkg/services/ghcrateengine/service_item_pricer.go @@ -36,7 +36,6 @@ func (p serviceItemPricer) PriceServiceItem(appCtx appcontext.AppContext, item m // createPricerGeneratedParams will throw an error if pricingParams is an empty slice // currently our pricers are returning empty slices for pricingParams // once all pricers have been updated to return pricingParams - // TODO: this conditional logic should be removed var displayParams models.PaymentServiceItemParams if len(pricingParams) > 0 { displayParams, err = createPricerGeneratedParams(appCtx, item.ID, pricingParams) From 1a0073e2fd9d3c9fe45a035fb45b2cc4c4ff3d5e Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 18:56:51 +0000 Subject: [PATCH 37/52] linehaul done, now it is time for tests and refinement please save me baby jesus in a tuxedo --- ...aram_values_to_service_params_table.up.sql | 3 +- .../per_unit_cents_lookup.go | 24 ++++- pkg/services/ghc_rate_engine.go | 2 +- .../intl_shipping_and_linehaul_pricer.go | 97 +++++++------------ .../ghcrateengine/pricer_helpers_intl.go | 2 +- 5 files changed, 61 insertions(+), 67 deletions(-) diff --git a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql index eec414779d0..63c1e404e50 100644 --- a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql +++ b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql @@ -61,7 +61,8 @@ INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,u ('c08f7ab1-6c3c-4627-b22f-1e987ba6f4f2'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','1e6257e9-757d-4d59-8846-727dd8a055e7','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), ('4d9ed9b0-957d-4e6a-a3d4-5e2e2784ef62'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','14a93209-370d-42f3-8ca2-479c953be839','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',true), ('6acb30b9-65a0-4902-85ed-1acb6f4ac930'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','5335e243-ab5b-4906-b84f-bd8c35ba64b3','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), - ('fd83c2ba-0c59-4598-81d6-b56cc8d9979d'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); + ('fd83c2ba-0c59-4598-81d6-b56cc8d9979d'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','2cbc2251-eb7d-4c69-a120-9a83785c994b','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false), + ('b370c895-e356-4d2c-a200-c2c67ac51011'::uuid,'9f3d551a-0725-430e-897e-80ee9add3ae9','597bb77e-0ce7-4ba2-9624-24300962625f','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957',false); -- inserting params fo IOSFSC INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go index 07670b009fa..a25913f8e2c 100644 --- a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go @@ -38,7 +38,6 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP } return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil } - if p.ServiceItem.ReService.Code == models.ReServiceCodeIHUPK { // IHUPK we need the rate area id for the destination address rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) @@ -57,6 +56,29 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP return "", fmt.Errorf("error fetching IHUPK per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, and rateAreaID: %s: %s", contractID, serviceID, isPeakPeriod, rateAreaID, err) } return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil + } else if p.ServiceItem.ReService.Code == models.ReServiceCodeISLH { + // IHUPK we need the rate area id for the destination address + originRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) + if err != nil && err != sql.ErrNoRows { + return "", fmt.Errorf("error fetching rate area id for origina address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + } + destRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.DestinationAddressID, p.ServiceItem.ReServiceID) + if err != nil && err != sql.ErrNoRows { + return "", fmt.Errorf("error fetching rate area id for destination address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + } + isPeakPeriod = ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) + var reIntlPrice models.ReIntlPrice + err = appCtx.DB().Q(). + Where("contract_id = ?", contractID). + Where("service_id = ?", serviceID). + Where("is_peak_period = ?", isPeakPeriod). + Where("origin_rate_area_id = ?", originRateAreaID). + Where("destination_rate_area_id = ?", destRateAreaID). + First(&reIntlPrice) + if err != nil { + return "", fmt.Errorf("error fetching ISLH per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, originRateAreaID: %s, and destRateAreaid: %s: %s", contractID, serviceID, isPeakPeriod, originRateAreaID, destRateAreaID, err) + } + return reIntlPrice.PerUnitCents.ToMillicents().ToCents().String(), nil } else { return "", fmt.Errorf("unsupported service code to retrieve service item param PerUnitCents") } diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 4a74692a5bb..b024ac1d4e3 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -237,7 +237,7 @@ type DomesticOriginSITFuelSurchargePricer interface { // //go:generate mockery --name IntlShippingAndLinehaulPricer type IntlShippingAndLinehaulPricer interface { - Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string, isPPM bool) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, perUnitCents int) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go index 2fec86a9b57..ca0624d75a2 100644 --- a/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go +++ b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go @@ -13,46 +13,40 @@ import ( "github.com/transcom/mymove/pkg/unit" ) +const islhPricerMinimumWeight = unit.Pound(500) + type intlShippingAndLinehaulPricer struct { } -// NewDomesticLinehaulPricer creates a new pricer for domestic linehaul services -func NewIntlShippingAndLinehaulPricer() services.DomesticLinehaulPricer { +func NewIntlShippingAndLinehaulPricer() services.IntlShippingAndLinehaulPricer { return &intlShippingAndLinehaulPricer{} } -// Price determines the price for a domestic linehaul -func (p intlShippingAndLinehaulPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { - // Validate parameters +func (p intlShippingAndLinehaulPricer) Price(appCtx appcontext.AppContext, contractCode string, referenceDate time.Time, distance unit.Miles, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { if len(contractCode) == 0 { return 0, nil, errors.New("ContractCode is required") } if referenceDate.IsZero() { - return 0, nil, errors.New("ReferenceDate is required") + return 0, nil, errors.New("referenceDate is required") } - if !isPPM && weight < dlhPricerMinimumWeight { - return 0, nil, fmt.Errorf("Weight must be at least %d", dlhPricerMinimumWeight) + if weight < islhPricerMinimumWeight { + return 0, nil, fmt.Errorf("weight must be at least %d", islhPricerMinimumWeight) } - if len(serviceArea) == 0 { - return 0, nil, errors.New("ServiceArea is required") + if perUnitCents == 0 { + return 0, nil, errors.New("PerUnitCents is required") } isPeakPeriod := IsPeakPeriod(referenceDate) - finalWeight := weight - - if isPPM && weight < dlhPricerMinimumWeight { - finalWeight = dlhPricerMinimumWeight - } - domesticLinehaulPrice, err := fetchDomesticLinehaulPrice(appCtx, contractCode, isPeakPeriod, distance, finalWeight, serviceArea) + contract, err := fetchContractsByContractCode(appCtx, contractCode) if err != nil { - return unit.Cents(0), nil, fmt.Errorf("could not fetch domestic linehaul rate: %w", err) + return 0, nil, fmt.Errorf("could not find contract with code: %s: %w", contractCode, err) } - basePrice := domesticLinehaulPrice.PriceMillicents.Float64() / 1000 + basePrice := float64(perUnitCents) escalatedPrice, contractYear, err := escalatePriceForContractYear( appCtx, - domesticLinehaulPrice.ContractID, + contract.ID, referenceDate, true, basePrice) @@ -60,26 +54,30 @@ func (p intlShippingAndLinehaulPricer) Price(appCtx appcontext.AppContext, contr return 0, nil, fmt.Errorf("could not calculate escalated price: %w", err) } - totalPrice := finalWeight.ToCWTFloat64() * distance.Float64() * escalatedPrice - totalPriceCents := unit.Cents(math.Round(totalPrice)) + escalatedPrice = escalatedPrice * weight.ToCWTFloat64() + totalPriceCents := unit.Cents(math.Round(escalatedPrice)) params := services.PricingDisplayParams{ - {Key: models.ServiceItemParamNameContractYearName, Value: contractYear.Name}, - {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(contractYear.EscalationCompounded)}, - {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(isPeakPeriod)}, - {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatFloat(domesticLinehaulPrice.PriceMillicents.ToDollarFloatNoRound(), 3)}, - } - - if isPPM && weight < dlhPricerMinimumWeight { - weightFactor := float64(weight) / float64(dlhPricerMinimumWeight) - cost := float64(weightFactor) * float64(totalPriceCents) - return unit.Cents(cost), params, nil - } + { + Key: models.ServiceItemParamNameContractYearName, + Value: contractYear.Name, + }, + { + Key: models.ServiceItemParamNameEscalationCompounded, + Value: FormatEscalation(contractYear.EscalationCompounded), + }, + { + Key: models.ServiceItemParamNameIsPeak, + Value: FormatBool(isPeakPeriod), + }, + { + Key: models.ServiceItemParamNamePriceRateOrFactor, + Value: FormatCents(unit.Cents(perUnitCents)), + }} return totalPriceCents, params, nil } -// PriceUsingParams determines the price for a domestic linehaul given PaymentServiceItemParams func (p intlShippingAndLinehaulPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) if err != nil { @@ -96,42 +94,15 @@ func (p intlShippingAndLinehaulPricer) PriceUsingParams(appCtx appcontext.AppCon return unit.Cents(0), nil, err } - serviceAreaOrigin, err := getParamString(params, models.ServiceItemParamNameServiceAreaOrigin) + weightBilled, err := getParamInt(params, models.ServiceItemParamNameWeightBilled) if err != nil { return unit.Cents(0), nil, err } - weightBilled, err := getParamInt(params, models.ServiceItemParamNameWeightBilled) + perUnitCents, err := getParamInt(params, models.ServiceItemParamNamePerUnitCents) if err != nil { return unit.Cents(0), nil, err } - var isPPM = false - if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { - // PPMs do not require minimums for a shipment's weight or distance - // this flag is passed into the Price function to ensure the weight and distance mins - // are not enforced for PPMs - isPPM = true - } - - return p.Price(appCtx, contractCode, referenceDate, unit.Miles(distance), unit.Pound(weightBilled), serviceAreaOrigin, isPPM) + return p.Price(appCtx, contractCode, referenceDate, unit.Miles(distance), unit.Pound(weightBilled), perUnitCents) } - -// func fetchDomesticLinehaulPrice(appCtx appcontext.AppContext, contractCode string, isPeakPeriod bool, distance unit.Miles, weight unit.Pound, serviceArea string) (models.ReDomesticLinehaulPrice, error) { -// var domesticLinehaulPrice models.ReDomesticLinehaulPrice -// err := appCtx.DB().Q(). -// Join("re_domestic_service_areas sa", "domestic_service_area_id = sa.id"). -// Join("re_contracts c", "re_domestic_linehaul_prices.contract_id = c.id"). -// Where("c.code = $1", contractCode). -// Where("re_domestic_linehaul_prices.is_peak_period = $2", isPeakPeriod). -// Where("$3 between weight_lower and weight_upper", weight). -// Where("$4 between miles_lower and miles_upper", distance). -// Where("sa.service_area = $5", serviceArea). -// First(&domesticLinehaulPrice) - -// if err != nil { -// return models.ReDomesticLinehaulPrice{}, err -// } - -// return domesticLinehaulPrice, nil -// } diff --git a/pkg/services/ghcrateengine/pricer_helpers_intl.go b/pkg/services/ghcrateengine/pricer_helpers_intl.go index 73428847e51..37f01ee9966 100644 --- a/pkg/services/ghcrateengine/pricer_helpers_intl.go +++ b/pkg/services/ghcrateengine/pricer_helpers_intl.go @@ -38,6 +38,7 @@ func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReS } escalatedPrice = escalatedPrice * weight.ToCWTFloat64() + totalCost := unit.Cents(math.Round(escalatedPrice)) displayParams := services.PricingDisplayParams{ { @@ -58,6 +59,5 @@ func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReS }, } - totalCost := unit.Cents(math.Round(escalatedPrice)) return totalCost, displayParams, nil } From d43303f650c2ca7a3e6751a6dc29294a2fd9636f Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 19:38:55 +0000 Subject: [PATCH 38/52] test for rate area id --- pkg/factory/address_factory.go | 10 +++++++++ pkg/factory/address_factory_test.go | 1 + pkg/models/re_rate_area.go | 10 ++++----- pkg/models/re_rate_area_test.go | 22 +++++++++++++++++++ .../per_unit_cents_lookup.go | 8 +++---- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/pkg/factory/address_factory.go b/pkg/factory/address_factory.go index 91a49da4445..d6b7dff6ce5 100644 --- a/pkg/factory/address_factory.go +++ b/pkg/factory/address_factory.go @@ -72,6 +72,16 @@ func BuildAddress(db *pop.Connection, customs []Customization, traits []Trait) m address.County = models.StringPointer("db nil when created") } + if db != nil { + usprc, err := models.FindByZipCode(db, address.PostalCode) + if err != nil { + return models.Address{} + } else { + address.UsPostRegionCityID = &usprc.ID + address.UsPostRegionCity = usprc + } + } + // If db is false, it's a stub. No need to create in database. if db != nil { mustCreate(db, &address) diff --git a/pkg/factory/address_factory_test.go b/pkg/factory/address_factory_test.go index 2e17e564605..7f72a13e9b6 100644 --- a/pkg/factory/address_factory_test.go +++ b/pkg/factory/address_factory_test.go @@ -40,6 +40,7 @@ func (suite *FactorySuite) TestBuildAddress() { suite.Equal(defaultPostalCode, address.PostalCode) suite.Equal(country.ID, *address.CountryId) suite.Equal(defaultCounty, *address.County) + suite.NotNil(*address.UsPostRegionCityID) }) suite.Run("Successful creation of an address with customization", func() { diff --git a/pkg/models/re_rate_area.go b/pkg/models/re_rate_area.go index 960f4258d8c..7b613b42a28 100644 --- a/pkg/models/re_rate_area.go +++ b/pkg/models/re_rate_area.go @@ -56,14 +56,12 @@ func FetchReRateAreaItem(tx *pop.Connection, contractID uuid.UUID, code string) } // a db stored proc that takes in an address id & a service code to get the rate area id for an address -func FetchRateAreaID(db *pop.Connection, addressID uuid.UUID, serviceID uuid.UUID) (uuid.UUID, error) { - if addressID != uuid.Nil && serviceID != uuid.Nil { +func FetchRateAreaID(db *pop.Connection, addressID uuid.UUID, serviceID uuid.UUID, contractID uuid.UUID) (uuid.UUID, error) { + if addressID != uuid.Nil && serviceID != uuid.Nil && contractID != uuid.Nil { var rateAreaID uuid.UUID - err := db.RawQuery("SELECT get_rate_area_id($1, $2)", addressID, serviceID). - First(&rateAreaID) - + err := db.RawQuery("SELECT get_rate_area_id($1, $2, $3)", addressID, serviceID, contractID).First(&rateAreaID) if err != nil { - return uuid.Nil, fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", addressID, serviceID, err) + return uuid.Nil, fmt.Errorf("error fetching rate area id for shipment ID: %s, service ID %s, and contract ID: %s: %s", addressID, serviceID, contractID, err) } return rateAreaID, nil } diff --git a/pkg/models/re_rate_area_test.go b/pkg/models/re_rate_area_test.go index a0769056783..87f310c2088 100644 --- a/pkg/models/re_rate_area_test.go +++ b/pkg/models/re_rate_area_test.go @@ -3,7 +3,9 @@ package models_test import ( "github.com/gofrs/uuid" + "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/testdatagen" ) func (suite *ModelSuite) TestReRateAreaValidation() { @@ -28,3 +30,23 @@ func (suite *ModelSuite) TestReRateAreaValidation() { suite.verifyValidationErrors(&emptyReRateArea, expErrors) }) } + +func (suite *ModelSuite) TestFetchRateAreaID() { + suite.Run("success - fetching a rate area ID", func() { + service := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeIHPK) + contract := testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + address := factory.BuildAddress(suite.DB(), nil, nil) + rateAreaId, err := models.FetchRateAreaID(suite.DB(), address.ID, service.ID, contract.ID) + suite.NotNil(rateAreaId) + suite.NoError(err) + }) + + suite.Run("fail - receive error when not all values are provided", func() { + var nilUuid uuid.UUID + contract := testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + address := factory.BuildAddress(suite.DB(), nil, nil) + rateAreaId, err := models.FetchRateAreaID(suite.DB(), address.ID, nilUuid, contract.ID) + suite.Equal(uuid.Nil, rateAreaId) + suite.Error(err) + }) +} diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go index a25913f8e2c..88a46c98e44 100644 --- a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go @@ -21,7 +21,7 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP contractID := s.ContractID if p.ServiceItem.ReService.Code == models.ReServiceCodeIHPK { // IHPK we need the rate area id for the pickup address - rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) + rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID, contractID) if err != nil { return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) } @@ -40,7 +40,7 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP } if p.ServiceItem.ReService.Code == models.ReServiceCodeIHUPK { // IHUPK we need the rate area id for the destination address - rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) + rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID, contractID) if err != nil && err != sql.ErrNoRows { return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) } @@ -58,11 +58,11 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil } else if p.ServiceItem.ReService.Code == models.ReServiceCodeISLH { // IHUPK we need the rate area id for the destination address - originRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID) + originRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID, contractID) if err != nil && err != sql.ErrNoRows { return "", fmt.Errorf("error fetching rate area id for origina address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) } - destRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.DestinationAddressID, p.ServiceItem.ReServiceID) + destRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.DestinationAddressID, p.ServiceItem.ReServiceID, contractID) if err != nil && err != sql.ErrNoRows { return "", fmt.Errorf("error fetching rate area id for destination address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) } From 776f7307919af7f5d3efeb963f0b812a75402cfb Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 20:34:42 +0000 Subject: [PATCH 39/52] added tests for service param value lookups folder --- .../per_unit_cents_lookup.go | 52 +++---- .../per_unit_cents_lookup_test.go | 132 ++++++++++++++++++ .../port_name_lookup_test.go | 87 ++++++++++++ 3 files changed, 246 insertions(+), 25 deletions(-) create mode 100644 pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go create mode 100644 pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go index 88a46c98e44..d2062218620 100644 --- a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go @@ -1,7 +1,6 @@ package serviceparamvaluelookups import ( - "database/sql" "fmt" "github.com/transcom/mymove/pkg/appcontext" @@ -16,16 +15,17 @@ type PerUnitCentsLookup struct { } func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemParamKeyData) (string, error) { - var isPeakPeriod bool serviceID := p.ServiceItem.ReServiceID contractID := s.ContractID - if p.ServiceItem.ReService.Code == models.ReServiceCodeIHPK { - // IHPK we need the rate area id for the pickup address - rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID, contractID) + + switch p.ServiceItem.ReService.Code { + case models.ReServiceCodeIHPK: + // IHPK: Need rate area ID for the pickup address + rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, serviceID, contractID) if err != nil { - return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, serviceID, err) } - isPeakPeriod = ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) + isPeakPeriod := ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) var reIntlOtherPrice models.ReIntlOtherPrice err = appCtx.DB().Q(). Where("contract_id = ?", contractID). @@ -37,14 +37,14 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP return "", fmt.Errorf("error fetching IHPK per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, and rateAreaID: %s: %s", contractID, serviceID, isPeakPeriod, rateAreaID, err) } return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil - } - if p.ServiceItem.ReService.Code == models.ReServiceCodeIHUPK { - // IHUPK we need the rate area id for the destination address - rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID, contractID) - if err != nil && err != sql.ErrNoRows { - return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + + case models.ReServiceCodeIHUPK: + // IHUPK: Need rate area ID for the destination address + rateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, serviceID, contractID) + if err != nil { + return "", fmt.Errorf("error fetching rate area id for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, serviceID, err) } - isPeakPeriod = ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) + isPeakPeriod := ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) var reIntlOtherPrice models.ReIntlOtherPrice err = appCtx.DB().Q(). Where("contract_id = ?", contractID). @@ -56,17 +56,18 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP return "", fmt.Errorf("error fetching IHUPK per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, and rateAreaID: %s: %s", contractID, serviceID, isPeakPeriod, rateAreaID, err) } return reIntlOtherPrice.PerUnitCents.ToMillicents().ToCents().String(), nil - } else if p.ServiceItem.ReService.Code == models.ReServiceCodeISLH { - // IHUPK we need the rate area id for the destination address - originRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, p.ServiceItem.ReServiceID, contractID) - if err != nil && err != sql.ErrNoRows { - return "", fmt.Errorf("error fetching rate area id for origina address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + + case models.ReServiceCodeISLH: + // ISLH: Need rate area IDs for origin and destination + originRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.PickupAddressID, serviceID, contractID) + if err != nil { + return "", fmt.Errorf("error fetching rate area id for origin address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, serviceID, err) } - destRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.DestinationAddressID, p.ServiceItem.ReServiceID, contractID) - if err != nil && err != sql.ErrNoRows { - return "", fmt.Errorf("error fetching rate area id for destination address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, p.ServiceItem.ReServiceID, err) + destRateAreaID, err := models.FetchRateAreaID(appCtx.DB(), *p.MTOShipment.DestinationAddressID, serviceID, contractID) + if err != nil { + return "", fmt.Errorf("error fetching rate area id for destination address for shipment ID: %s and service ID %s: %s", p.MTOShipment.ID, serviceID, err) } - isPeakPeriod = ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) + isPeakPeriod := ghcrateengine.IsPeakPeriod(*p.MTOShipment.RequestedPickupDate) var reIntlPrice models.ReIntlPrice err = appCtx.DB().Q(). Where("contract_id = ?", contractID). @@ -76,10 +77,11 @@ func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemP Where("destination_rate_area_id = ?", destRateAreaID). First(&reIntlPrice) if err != nil { - return "", fmt.Errorf("error fetching ISLH per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, originRateAreaID: %s, and destRateAreaid: %s: %s", contractID, serviceID, isPeakPeriod, originRateAreaID, destRateAreaID, err) + return "", fmt.Errorf("error fetching ISLH per unit cents for contractID: %s, serviceID %s, isPeakPeriod: %t, originRateAreaID: %s, and destRateAreaID: %s: %s", contractID, serviceID, isPeakPeriod, originRateAreaID, destRateAreaID, err) } return reIntlPrice.PerUnitCents.ToMillicents().ToCents().String(), nil - } else { + + default: return "", fmt.Errorf("unsupported service code to retrieve service item param PerUnitCents") } } diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go new file mode 100644 index 00000000000..4d9ceab2512 --- /dev/null +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go @@ -0,0 +1,132 @@ +package serviceparamvaluelookups + +import ( + "time" + + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/factory" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/testdatagen" +) + +func (suite *ServiceParamValueLookupsSuite) TestPerUnitCentsLookup() { + key := models.ServiceItemParamNamePerUnitCents + var mtoServiceItem models.MTOServiceItem + setupTestData := func(serviceCode models.ReServiceCode) { + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + mtoServiceItem = factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.ReService{ + Code: serviceCode, + }, + }, + }, []factory.Trait{factory.GetTraitAvailableToPrimeMove}) + + } + + suite.Run("success - returns perUnitCent value for IHPK", func() { + setupTestData(models.ReServiceCodeIHPK) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + perUnitCents, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.FatalNoError(err) + suite.Equal(perUnitCents, "6997") + }) + + suite.Run("success - returns perUnitCent value for IHUPK", func() { + setupTestData(models.ReServiceCodeIHUPK) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + perUnitCents, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.FatalNoError(err) + suite.Equal(perUnitCents, "752") + }) + + suite.Run("success - returns perUnitCent value for ISLH", func() { + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + }, + }, + }, nil) + pickupAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "Tester Address", + City: "Des Moines", + State: "IA", + PostalCode: "50314", + IsOconus: models.BoolPointer(false), + }, + }, + }, nil) + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + PickupAddressID: &pickupAddress.ID, + DestinationAddressID: &destinationAddress.ID, + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + }, nil) + mtoServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeISLH, + }, + }, + }, nil) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + perUnitCents, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.FatalNoError(err) + suite.Equal(perUnitCents, "1605") + }) + + suite.Run("failure - unauthorized service code", func() { + setupTestData(models.ReServiceCodeDUPK) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + perUnitCents, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.Error(err) + suite.Equal(perUnitCents, "") + }) +} diff --git a/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go b/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go new file mode 100644 index 00000000000..b0ccb4b2bfe --- /dev/null +++ b/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go @@ -0,0 +1,87 @@ +package serviceparamvaluelookups + +import ( + "time" + + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/factory" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/testdatagen" +) + +func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { + key := models.ServiceItemParamNamePortName + var mtoServiceItem models.MTOServiceItem + setupTestData := func(serviceCode models.ReServiceCode, portID uuid.UUID) { + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + if serviceCode == models.ReServiceCodePOEFSC { + mtoServiceItem = factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.ReService{ + Code: serviceCode, + }, + }, + { + Model: models.MTOServiceItem{ + POELocationID: &portID, + }, + }, + }, []factory.Trait{factory.GetTraitAvailableToPrimeMove}) + } else { + mtoServiceItem = factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.ReService{ + Code: serviceCode, + }, + }, + { + Model: models.MTOServiceItem{ + PODLocationID: &portID, + }, + }, + }, []factory.Trait{factory.GetTraitAvailableToPrimeMove}) + } + } + + suite.Run("success - returns PortName value for POEFSC", func() { + port := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "SEA", + }, + }, + }, nil) + setupTestData(models.ReServiceCodePOEFSC, port.ID) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + portName, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.FatalNoError(err) + suite.Equal(portName, "SEATTLE TACOMA INTL") + }) + + suite.Run("success - returns PortName value for PODFSC", func() { + port := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + setupTestData(models.ReServiceCodePODFSC, port.ID) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + portName, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.FatalNoError(err) + suite.Equal(portName, "PORTLAND INTL") + }) +} From 440003f6a5975a15e24d6ce328a0b87b272cac12 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 20:39:15 +0000 Subject: [PATCH 40/52] mocks --- pkg/services/ghc_rate_engine.go | 6 +- pkg/services/mocks/IntlHHGPackPricer.go | 109 ++++++++++++++++++ pkg/services/mocks/IntlHHGUnpackPricer.go | 109 ++++++++++++++++++ .../mocks/IntlPortFuelSurchargePricer.go | 109 ++++++++++++++++++ .../mocks/IntlShippingAndLinehaulPricer.go | 109 ++++++++++++++++++ 5 files changed, 439 insertions(+), 3 deletions(-) create mode 100644 pkg/services/mocks/IntlHHGPackPricer.go create mode 100644 pkg/services/mocks/IntlHHGUnpackPricer.go create mode 100644 pkg/services/mocks/IntlPortFuelSurchargePricer.go create mode 100644 pkg/services/mocks/IntlShippingAndLinehaulPricer.go diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index b024ac1d4e3..8b3ef07de0f 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -241,7 +241,7 @@ type IntlShippingAndLinehaulPricer interface { ParamsPricer } -// IntlHHGPackPricer prices international packing for an HHG shipment within a move +// IntlHHGPackPricer prices international packing for an iHHG shipment within a move // //go:generate mockery --name IntlHHGPackPricer type IntlHHGPackPricer interface { @@ -249,7 +249,7 @@ type IntlHHGPackPricer interface { ParamsPricer } -// IntlHHGUnpackPricer prices international unpacking for an HHG shipment within a move +// IntlHHGUnpackPricer prices international unpacking for an iHHG shipment within a move // //go:generate mockery --name IntlHHGUnpackPricer type IntlHHGUnpackPricer interface { @@ -257,7 +257,7 @@ type IntlHHGUnpackPricer interface { ParamsPricer } -// IntlPortFuelSurchargePricer prices the POEFSC/PODFSC service items on a shipment within a move +// IntlPortFuelSurchargePricer prices the POEFSC/PODFSC service items on an iHHG shipment within a move // //go:generate mockery --name IntlPortFuelSurchargePricer type IntlPortFuelSurchargePricer interface { diff --git a/pkg/services/mocks/IntlHHGPackPricer.go b/pkg/services/mocks/IntlHHGPackPricer.go new file mode 100644 index 00000000000..a12bed589ec --- /dev/null +++ b/pkg/services/mocks/IntlHHGPackPricer.go @@ -0,0 +1,109 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + appcontext "github.com/transcom/mymove/pkg/appcontext" + + models "github.com/transcom/mymove/pkg/models" + + services "github.com/transcom/mymove/pkg/services" + + time "time" + + unit "github.com/transcom/mymove/pkg/unit" +) + +// IntlHHGPackPricer is an autogenerated mock type for the IntlHHGPackPricer type +type IntlHHGPackPricer struct { + mock.Mock +} + +// Price provides a mock function with given fields: appCtx, contractCode, requestedPickupDate, weight, perUnitCents +func (_m *IntlHHGPackPricer) Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + + if len(ret) == 0 { + panic("no return value specified for Price") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) unit.Cents); ok { + r0 = rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) services.PricingDisplayParams); ok { + r1 = rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) error); ok { + r2 = rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// PriceUsingParams provides a mock function with given fields: appCtx, params +func (_m *IntlHHGPackPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, params) + + if len(ret) == 0 { + panic("no return value specified for PriceUsingParams") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, params) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) unit.Cents); ok { + r0 = rf(appCtx, params) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.PaymentServiceItemParams) services.PricingDisplayParams); ok { + r1 = rf(appCtx, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.PaymentServiceItemParams) error); ok { + r2 = rf(appCtx, params) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// NewIntlHHGPackPricer creates a new instance of IntlHHGPackPricer. 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 NewIntlHHGPackPricer(t interface { + mock.TestingT + Cleanup(func()) +}) *IntlHHGPackPricer { + mock := &IntlHHGPackPricer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/services/mocks/IntlHHGUnpackPricer.go b/pkg/services/mocks/IntlHHGUnpackPricer.go new file mode 100644 index 00000000000..d06f97791d5 --- /dev/null +++ b/pkg/services/mocks/IntlHHGUnpackPricer.go @@ -0,0 +1,109 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + appcontext "github.com/transcom/mymove/pkg/appcontext" + + models "github.com/transcom/mymove/pkg/models" + + services "github.com/transcom/mymove/pkg/services" + + time "time" + + unit "github.com/transcom/mymove/pkg/unit" +) + +// IntlHHGUnpackPricer is an autogenerated mock type for the IntlHHGUnpackPricer type +type IntlHHGUnpackPricer struct { + mock.Mock +} + +// Price provides a mock function with given fields: appCtx, contractCode, requestedPickupDate, weight, perUnitCents +func (_m *IntlHHGUnpackPricer) Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + + if len(ret) == 0 { + panic("no return value specified for Price") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) unit.Cents); ok { + r0 = rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) services.PricingDisplayParams); ok { + r1 = rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time, unit.Pound, int) error); ok { + r2 = rf(appCtx, contractCode, requestedPickupDate, weight, perUnitCents) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// PriceUsingParams provides a mock function with given fields: appCtx, params +func (_m *IntlHHGUnpackPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, params) + + if len(ret) == 0 { + panic("no return value specified for PriceUsingParams") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, params) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) unit.Cents); ok { + r0 = rf(appCtx, params) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.PaymentServiceItemParams) services.PricingDisplayParams); ok { + r1 = rf(appCtx, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.PaymentServiceItemParams) error); ok { + r2 = rf(appCtx, params) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// NewIntlHHGUnpackPricer creates a new instance of IntlHHGUnpackPricer. 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 NewIntlHHGUnpackPricer(t interface { + mock.TestingT + Cleanup(func()) +}) *IntlHHGUnpackPricer { + mock := &IntlHHGUnpackPricer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/services/mocks/IntlPortFuelSurchargePricer.go b/pkg/services/mocks/IntlPortFuelSurchargePricer.go new file mode 100644 index 00000000000..48e396d017e --- /dev/null +++ b/pkg/services/mocks/IntlPortFuelSurchargePricer.go @@ -0,0 +1,109 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + appcontext "github.com/transcom/mymove/pkg/appcontext" + + models "github.com/transcom/mymove/pkg/models" + + services "github.com/transcom/mymove/pkg/services" + + time "time" + + unit "github.com/transcom/mymove/pkg/unit" +) + +// IntlPortFuelSurchargePricer is an autogenerated mock type for the IntlPortFuelSurchargePricer type +type IntlPortFuelSurchargePricer struct { + mock.Mock +} + +// Price provides a mock function with given fields: appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName +func (_m *IntlPortFuelSurchargePricer) Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, portName string) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + + if len(ret) == 0 { + panic("no return value specified for Price") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) unit.Cents); ok { + r0 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) services.PricingDisplayParams); ok { + r1 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) error); ok { + r2 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// PriceUsingParams provides a mock function with given fields: appCtx, params +func (_m *IntlPortFuelSurchargePricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, params) + + if len(ret) == 0 { + panic("no return value specified for PriceUsingParams") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, params) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) unit.Cents); ok { + r0 = rf(appCtx, params) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.PaymentServiceItemParams) services.PricingDisplayParams); ok { + r1 = rf(appCtx, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.PaymentServiceItemParams) error); ok { + r2 = rf(appCtx, params) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// NewIntlPortFuelSurchargePricer creates a new instance of IntlPortFuelSurchargePricer. 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 NewIntlPortFuelSurchargePricer(t interface { + mock.TestingT + Cleanup(func()) +}) *IntlPortFuelSurchargePricer { + mock := &IntlPortFuelSurchargePricer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/services/mocks/IntlShippingAndLinehaulPricer.go b/pkg/services/mocks/IntlShippingAndLinehaulPricer.go new file mode 100644 index 00000000000..c6e4ca2b557 --- /dev/null +++ b/pkg/services/mocks/IntlShippingAndLinehaulPricer.go @@ -0,0 +1,109 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + appcontext "github.com/transcom/mymove/pkg/appcontext" + + models "github.com/transcom/mymove/pkg/models" + + services "github.com/transcom/mymove/pkg/services" + + time "time" + + unit "github.com/transcom/mymove/pkg/unit" +) + +// IntlShippingAndLinehaulPricer is an autogenerated mock type for the IntlShippingAndLinehaulPricer type +type IntlShippingAndLinehaulPricer struct { + mock.Mock +} + +// Price provides a mock function with given fields: appCtx, contractCode, requestedPickupDate, distance, weight, perUnitCents +func (_m *IntlShippingAndLinehaulPricer) Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, perUnitCents int) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, contractCode, requestedPickupDate, distance, weight, perUnitCents) + + if len(ret) == 0 { + panic("no return value specified for Price") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, int) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, contractCode, requestedPickupDate, distance, weight, perUnitCents) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, int) unit.Cents); ok { + r0 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, perUnitCents) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, int) services.PricingDisplayParams); ok { + r1 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, perUnitCents) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, int) error); ok { + r2 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, perUnitCents) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// PriceUsingParams provides a mock function with given fields: appCtx, params +func (_m *IntlShippingAndLinehaulPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, params) + + if len(ret) == 0 { + panic("no return value specified for PriceUsingParams") + } + + var r0 unit.Cents + var r1 services.PricingDisplayParams + var r2 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, params) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.PaymentServiceItemParams) unit.Cents); ok { + r0 = rf(appCtx, params) + } else { + r0 = ret.Get(0).(unit.Cents) + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.PaymentServiceItemParams) services.PricingDisplayParams); ok { + r1 = rf(appCtx, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(services.PricingDisplayParams) + } + } + + if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.PaymentServiceItemParams) error); ok { + r2 = rf(appCtx, params) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// NewIntlShippingAndLinehaulPricer creates a new instance of IntlShippingAndLinehaulPricer. 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 NewIntlShippingAndLinehaulPricer(t interface { + mock.TestingT + Cleanup(func()) +}) *IntlShippingAndLinehaulPricer { + mock := &IntlShippingAndLinehaulPricer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} From 88cba28f91b0d613609c6028c8e90c9d85944f7d Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 22:17:22 +0000 Subject: [PATCH 41/52] tests on tests on tests --- .../intl_hhg_pack_pricer_test.go | 115 ++++++++++ .../intl_hhg_unpack_pricer_test.go | 114 ++++++++++ .../intl_port_fuel_surcharge_pricer_test.go | 209 ++++++++++++++++++ .../intl_shipping_and_linehaul_pricer.go | 2 +- .../intl_shipping_and_linehaul_pricer_test.go | 144 ++++++++++++ .../ghcrateengine/pricer_helpers_intl.go | 5 +- .../ghcrateengine/pricer_helpers_intl_test.go | 46 ++++ .../ghcrateengine/pricer_helpers_test.go | 2 +- .../ghcrateengine/pricer_query_helpers.go | 2 +- .../CreatePaymentRequestForm.jsx | 5 +- .../CreatePaymentRequestForm.test.jsx | 6 + 11 files changed, 645 insertions(+), 5 deletions(-) create mode 100644 pkg/services/ghcrateengine/intl_hhg_pack_pricer_test.go create mode 100644 pkg/services/ghcrateengine/intl_hhg_unpack_pricer_test.go create mode 100644 pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go create mode 100644 pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer_test.go create mode 100644 pkg/services/ghcrateengine/pricer_helpers_intl_test.go diff --git a/pkg/services/ghcrateengine/intl_hhg_pack_pricer_test.go b/pkg/services/ghcrateengine/intl_hhg_pack_pricer_test.go new file mode 100644 index 00000000000..9674775b906 --- /dev/null +++ b/pkg/services/ghcrateengine/intl_hhg_pack_pricer_test.go @@ -0,0 +1,115 @@ +package ghcrateengine + +import ( + "fmt" + "strconv" + "time" + + "github.com/transcom/mymove/pkg/factory" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" +) + +const ( + ihpkTestContractYearName = "Base Period Year 1" + ihpkTestPerUnitCents = unit.Cents(15000) + ihpkTestTotalCost = unit.Cents(315000) + ihpkTestIsPeakPeriod = true + ihpkTestEscalationCompounded = 1.0000 + ihpkTestWeight = unit.Pound(2100) + ihpkTestPriceCents = unit.Cents(193064) +) + +var ihpkTestRequestedPickupDate = time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC) + +func (suite *GHCRateEngineServiceSuite) TestIntlHHGPackPricer() { + pricer := NewIntlHHGPackPricer() + + suite.Run("success using PaymentServiceItemParams", func() { + paymentServiceItem := suite.setupIntlPackServiceItem() + + totalCost, displayParams, err := pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.NoError(err) + suite.Equal(ihpkTestTotalCost, totalCost) + + expectedParams := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameContractYearName, Value: ihpkTestContractYearName}, + {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(ihpkTestEscalationCompounded)}, + {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(ihpkTestIsPeakPeriod)}, + {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatCents(ihpkTestPerUnitCents)}, + } + suite.validatePricerCreatedParams(expectedParams, displayParams) + }) + + suite.Run("invalid parameters to PriceUsingParams", func() { + paymentServiceItem := suite.setupIntlPackServiceItem() + + // WeightBilled + paymentServiceItem.PaymentServiceItemParams[3].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err := pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to an int", models.ServiceItemParamNameWeightBilled)) + + // PerUnitCents + paymentServiceItem.PaymentServiceItemParams[2].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to an int", models.ServiceItemParamNamePerUnitCents)) + + // ReferenceDate + paymentServiceItem.PaymentServiceItemParams[1].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to a time", models.ServiceItemParamNameReferenceDate)) + + // ContractCode + paymentServiceItem.PaymentServiceItemParams[0].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to a string", models.ServiceItemParamNameContractCode)) + }) +} + +func (suite *GHCRateEngineServiceSuite) setupIntlPackServiceItem() models.PaymentServiceItem { + contract := testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + startDate := time.Date(2018, time.January, 1, 12, 0, 0, 0, time.UTC) + endDate := time.Date(2018, time.December, 31, 12, 0, 0, 0, time.UTC) + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + Contract: contract, + ContractID: contract.ID, + StartDate: startDate, + EndDate: endDate, + Escalation: 1.0, + EscalationCompounded: 1.0, + }, + }) + return factory.BuildPaymentServiceItemWithParams( + suite.DB(), + models.ReServiceCodeIHPK, + []factory.CreatePaymentServiceItemParams{ + { + Key: models.ServiceItemParamNameContractCode, + KeyType: models.ServiceItemParamTypeString, + Value: contract.Code, + }, + { + Key: models.ServiceItemParamNameReferenceDate, + KeyType: models.ServiceItemParamTypeDate, + Value: ihpkTestRequestedPickupDate.Format(DateParamFormat), + }, + { + Key: models.ServiceItemParamNamePerUnitCents, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(ihpkTestPerUnitCents)), + }, + { + Key: models.ServiceItemParamNameWeightBilled, + KeyType: models.ServiceItemParamTypeInteger, + Value: strconv.Itoa(ihpkTestWeight.Int()), + }, + }, nil, nil, + ) +} diff --git a/pkg/services/ghcrateengine/intl_hhg_unpack_pricer_test.go b/pkg/services/ghcrateengine/intl_hhg_unpack_pricer_test.go new file mode 100644 index 00000000000..322027b37b5 --- /dev/null +++ b/pkg/services/ghcrateengine/intl_hhg_unpack_pricer_test.go @@ -0,0 +1,114 @@ +package ghcrateengine + +import ( + "fmt" + "strconv" + "time" + + "github.com/transcom/mymove/pkg/factory" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" +) + +const ( + ihupkTestContractYearName = "Base Period Year 1" + ihupkTestPerUnitCents = unit.Cents(1200) + ihupkTestTotalCost = unit.Cents(25200) + ihupkTestIsPeakPeriod = true + ihupkTestEscalationCompounded = 1.0000 + ihpukTestWeight = unit.Pound(2100) +) + +var ihupkTestRequestedPickupDate = time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC) + +func (suite *GHCRateEngineServiceSuite) TestIntlHHGUnpackPricer() { + pricer := NewIntlHHGUnpackPricer() + + suite.Run("success using PaymentServiceItemParams", func() { + paymentServiceItem := suite.setupIntlUnpackServiceItem() + + totalCost, displayParams, err := pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.NoError(err) + suite.Equal(ihupkTestTotalCost, totalCost) + + expectedParams := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameContractYearName, Value: ihupkTestContractYearName}, + {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(ihupkTestEscalationCompounded)}, + {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(ihupkTestIsPeakPeriod)}, + {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatCents(ihupkTestPerUnitCents)}, + } + suite.validatePricerCreatedParams(expectedParams, displayParams) + }) + + suite.Run("invalid parameters to PriceUsingParams", func() { + paymentServiceItem := suite.setupIntlPackServiceItem() + + // WeightBilled + paymentServiceItem.PaymentServiceItemParams[3].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err := pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to an int", models.ServiceItemParamNameWeightBilled)) + + // PerUnitCents + paymentServiceItem.PaymentServiceItemParams[2].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to an int", models.ServiceItemParamNamePerUnitCents)) + + // ReferenceDate + paymentServiceItem.PaymentServiceItemParams[1].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to a time", models.ServiceItemParamNameReferenceDate)) + + // ContractCode + paymentServiceItem.PaymentServiceItemParams[0].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to a string", models.ServiceItemParamNameContractCode)) + }) +} + +func (suite *GHCRateEngineServiceSuite) setupIntlUnpackServiceItem() models.PaymentServiceItem { + contract := testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + startDate := time.Date(2018, time.January, 1, 12, 0, 0, 0, time.UTC) + endDate := time.Date(2018, time.December, 31, 12, 0, 0, 0, time.UTC) + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + Contract: contract, + ContractID: contract.ID, + StartDate: startDate, + EndDate: endDate, + Escalation: 1.0, + EscalationCompounded: 1.0, + }, + }) + return factory.BuildPaymentServiceItemWithParams( + suite.DB(), + models.ReServiceCodeIHUPK, + []factory.CreatePaymentServiceItemParams{ + { + Key: models.ServiceItemParamNameContractCode, + KeyType: models.ServiceItemParamTypeString, + Value: contract.Code, + }, + { + Key: models.ServiceItemParamNameReferenceDate, + KeyType: models.ServiceItemParamTypeDate, + Value: ihupkTestRequestedPickupDate.Format(DateParamFormat), + }, + { + Key: models.ServiceItemParamNamePerUnitCents, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(ihupkTestPerUnitCents)), + }, + { + Key: models.ServiceItemParamNameWeightBilled, + KeyType: models.ServiceItemParamTypeInteger, + Value: strconv.Itoa(ihpukTestWeight.Int()), + }, + }, nil, nil, + ) +} diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go new file mode 100644 index 00000000000..9c07773bdb8 --- /dev/null +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go @@ -0,0 +1,209 @@ +package ghcrateengine + +import ( + "fmt" + "time" + + "github.com/gofrs/uuid" + + "github.com/transcom/mymove/pkg/apperror" + "github.com/transcom/mymove/pkg/factory" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" +) + +const ( + intlPortFscTestDistance = unit.Miles(2276) + intlPortFscTestWeight = unit.Pound(4025) + intlPortFscWeightDistanceMultiplier = float64(0.000417) + intlPortFscFuelPrice = unit.Millicents(281400) + intlPortFscPriceCents = unit.Cents(2980) + intlPortFscPortName = "PORTLAND INTL" +) + +var intlPortFscActualPickupDate = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) + +func (suite *GHCRateEngineServiceSuite) TestIntlPortFuelSurchargePricer() { + intlPortFuelSurchargePricer := NewPortFuelSurchargePricer() + + intlPortFscPriceDifferenceInCents := (intlPortFscFuelPrice - baseGHCDieselFuelPrice).Float64() / 1000.0 + intlPortFscMultiplier := intlPortFscWeightDistanceMultiplier * intlPortFscTestDistance.Float64() + + suite.Run("success using PaymentServiceItemParams", func() { + paymentServiceItem := suite.setupPortFuelSurchargeServiceItem() + priceCents, displayParams, err := intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.NoError(err) + suite.Equal(intlPortFscPriceCents, priceCents) + + expectedParams := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameFSCPriceDifferenceInCents, Value: FormatFloat(intlPortFscPriceDifferenceInCents, 1)}, + {Key: models.ServiceItemParamNameFSCMultiplier, Value: FormatFloat(intlPortFscMultiplier, 7)}, + } + suite.validatePricerCreatedParams(expectedParams, displayParams) + }) + + suite.Run("success without PaymentServiceItemParams", func() { + priceCents, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + suite.NoError(err) + suite.Equal(intlPortFscPriceCents, priceCents) + }) + + suite.Run("sending PaymentServiceItemParams without expected param", func() { + _, _, err := intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), models.PaymentServiceItemParams{}) + suite.Error(err) + }) + + suite.Run("fails using PaymentServiceItemParams with below minimum weight for WeightBilled", func() { + paymentServiceItem := suite.setupPortFuelSurchargeServiceItem() + paramsWithBelowMinimumWeight := paymentServiceItem.PaymentServiceItemParams + weightBilledIndex := 2 + if paramsWithBelowMinimumWeight[weightBilledIndex].ServiceItemParamKey.Key != models.ServiceItemParamNameWeightBilled { + suite.FailNow("failed", "Test needs to adjust the weight of %s but the index is pointing to %s ", models.ServiceItemParamNameWeightBilled, paramsWithBelowMinimumWeight[4].ServiceItemParamKey.Key) + } + paramsWithBelowMinimumWeight[weightBilledIndex].Value = "200" + priceCents, _, err := intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), paramsWithBelowMinimumWeight) + if suite.Error(err) { + suite.Equal("weight must be a minimum of 500", err.Error()) + suite.Equal(unit.Cents(0), priceCents) + } + }) + + suite.Run("FSC is negative if fuel price from EIA is below $2.50", func() { + priceCents, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, 242400, intlPortFscPortName) + suite.NoError(err) + suite.Equal(unit.Cents(-721), priceCents) + }) + + suite.Run("Price validation errors", func() { + + // No actual pickup date + _, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), time.Time{}, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + suite.Error(err) + suite.Equal("ActualPickupDate is required", err.Error()) + + // No distance + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, unit.Miles(0), intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + suite.Error(err) + suite.Equal("Distance must be greater than 0", err.Error()) + + // No weight + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, unit.Pound(0), intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + suite.Error(err) + suite.Equal(fmt.Sprintf("weight must be a minimum of %d", minDomesticWeight), err.Error()) + + // No weight based distance multiplier + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, 0, intlPortFscFuelPrice, intlPortFscPortName) + suite.Error(err) + suite.Equal("WeightBasedDistanceMultiplier is required", err.Error()) + + // No EIA fuel price + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, 0, intlPortFscPortName) + suite.Error(err) + suite.Equal("EIAFuelPrice is required", err.Error()) + }) + + suite.Run("PriceUsingParams validation errors", func() { + paymentServiceItem := suite.setupPortFuelSurchargeServiceItem() + paramsWithBelowMinimumWeight := paymentServiceItem.PaymentServiceItemParams + weightBilledIndex := 2 + if paramsWithBelowMinimumWeight[weightBilledIndex].ServiceItemParamKey.Key != models.ServiceItemParamNameWeightBilled { + suite.FailNow("failed", "Test needs to adjust the weight of %s but the index is pointing to %s ", models.ServiceItemParamNameWeightBilled, paramsWithBelowMinimumWeight[4].ServiceItemParamKey.Key) + } + paramsWithBelowMinimumWeight[weightBilledIndex].Value = "200" + + // No ActualPickupDate + missingActualPickupDate := suite.removeOnePaymentServiceItem(paymentServiceItem.PaymentServiceItemParams, models.ServiceItemParamNameActualPickupDate) + _, _, err := intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), missingActualPickupDate) + suite.Error(err) + suite.Equal("could not find param with key ActualPickupDate", err.Error()) + + // No WeightBilled + missingWeightBilled := suite.removeOnePaymentServiceItem(paymentServiceItem.PaymentServiceItemParams, models.ServiceItemParamNameWeightBilled) + _, _, err = intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), missingWeightBilled) + suite.Error(err) + suite.Equal("could not find param with key WeightBilled", err.Error()) + + // No FSCWeightBasedDistanceMultiplier + missingFSCWeightBasedDistanceMultiplier := suite.removeOnePaymentServiceItem(paymentServiceItem.PaymentServiceItemParams, models.ServiceItemParamNameFSCWeightBasedDistanceMultiplier) + _, _, err = intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), missingFSCWeightBasedDistanceMultiplier) + suite.Error(err) + suite.Equal("could not find param with key FSCWeightBasedDistanceMultiplier", err.Error()) + + // No EIAFuelPrice + missingEIAFuelPrice := suite.removeOnePaymentServiceItem(paymentServiceItem.PaymentServiceItemParams, models.ServiceItemParamNameEIAFuelPrice) + _, _, err = intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), missingEIAFuelPrice) + suite.Error(err) + suite.Equal("could not find param with key EIAFuelPrice", err.Error()) + }) + + suite.Run("can't find distance", func() { + paymentServiceItem := suite.setupPortFuelSurchargeServiceItem() + paramsWithBelowMinimumWeight := paymentServiceItem.PaymentServiceItemParams + weightBilledIndex := 2 + if paramsWithBelowMinimumWeight[weightBilledIndex].ServiceItemParamKey.Key != models.ServiceItemParamNameWeightBilled { + suite.FailNow("failed", "Test needs to adjust the weight of %s but the index is pointing to %s ", models.ServiceItemParamNameWeightBilled, paramsWithBelowMinimumWeight[4].ServiceItemParamKey.Key) + } + paramsWithBelowMinimumWeight[weightBilledIndex].Value = "200" + + paramsWithBadReference := paymentServiceItem.PaymentServiceItemParams + paramsWithBadReference[0].PaymentServiceItemID = uuid.Nil + _, _, err := intlPortFuelSurchargePricer.PriceUsingParams(suite.AppContextForTest(), paramsWithBadReference) + suite.Error(err) + suite.IsType(apperror.NotFoundError{}, err) + }) +} + +func (suite *GHCRateEngineServiceSuite) setupPortFuelSurchargeServiceItem() models.PaymentServiceItem { + model := factory.BuildPaymentServiceItemWithParams( + suite.DB(), + models.ReServiceCodePOEFSC, + []factory.CreatePaymentServiceItemParams{ + { + Key: models.ServiceItemParamNameActualPickupDate, + KeyType: models.ServiceItemParamTypeDate, + Value: intlPortFscActualPickupDate.Format(DateParamFormat), + }, + { + Key: models.ServiceItemParamNameDistanceZip, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(intlPortFscTestDistance)), + }, + { + Key: models.ServiceItemParamNameWeightBilled, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(intlPortFscTestWeight)), + }, + { + Key: models.ServiceItemParamNameFSCWeightBasedDistanceMultiplier, + KeyType: models.ServiceItemParamTypeDecimal, + Value: fmt.Sprintf("%.7f", intlPortFscWeightDistanceMultiplier), + }, + { + Key: models.ServiceItemParamNameEIAFuelPrice, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(intlPortFscFuelPrice)), + }, + { + Key: models.ServiceItemParamNamePortName, + KeyType: models.ServiceItemParamTypeString, + Value: intlPortFscPortName, + }, + }, nil, nil, + ) + + var mtoServiceItem models.MTOServiceItem + err := suite.DB().Eager("MTOShipment").Find(&mtoServiceItem, model.MTOServiceItemID) + suite.NoError(err) + + distance := intlPortFscTestDistance + mtoServiceItem.MTOShipment.Distance = &distance + err = suite.DB().Save(&mtoServiceItem.MTOShipment) + suite.NoError(err) + + // the testdatagen factory has some dirty shipment data that we don't want to pass through to the pricer in the test + model.PaymentServiceItemParams[0].PaymentServiceItem.MTOServiceItem = models.MTOServiceItem{} + + return model +} diff --git a/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go index ca0624d75a2..3d0ea35c3ba 100644 --- a/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go +++ b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer.go @@ -38,7 +38,7 @@ func (p intlShippingAndLinehaulPricer) Price(appCtx appcontext.AppContext, contr isPeakPeriod := IsPeakPeriod(referenceDate) - contract, err := fetchContractsByContractCode(appCtx, contractCode) + contract, err := fetchContractByContractCode(appCtx, contractCode) if err != nil { return 0, nil, fmt.Errorf("could not find contract with code: %s: %w", contractCode, err) } diff --git a/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer_test.go b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer_test.go new file mode 100644 index 00000000000..ef3407b04f0 --- /dev/null +++ b/pkg/services/ghcrateengine/intl_shipping_and_linehaul_pricer_test.go @@ -0,0 +1,144 @@ +package ghcrateengine + +import ( + "fmt" + "strconv" + "time" + + "github.com/transcom/mymove/pkg/factory" + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" +) + +const ( + islhTestContractYearName = "Base Period Year 1" + islhTestPerUnitCents = unit.Cents(15000) + islhTestTotalCost = unit.Cents(315000) + islhTestIsPeakPeriod = true + islhTestEscalationCompounded = 1.0000 + islhTestWeight = unit.Pound(2100) + islhTestDistance = unit.Miles(1201) +) + +var islhTestRequestedPickupDate = time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC) + +func (suite *GHCRateEngineServiceSuite) TestIntlShippingAndLinehaulPricer() { + pricer := NewIntlShippingAndLinehaulPricer() + + suite.Run("success using PaymentServiceItemParams", func() { + paymentServiceItem := suite.setupIntlShippingAndLinehaulServiceItem() + + totalCost, displayParams, err := pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.NoError(err) + suite.Equal(islhTestTotalCost, totalCost) + + expectedParams := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameContractYearName, Value: islhTestContractYearName}, + {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(islhTestEscalationCompounded)}, + {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(islhTestIsPeakPeriod)}, + {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatCents(islhTestPerUnitCents)}, + } + suite.validatePricerCreatedParams(expectedParams, displayParams) + }) + + suite.Run("invalid parameters to PriceUsingParams", func() { + paymentServiceItem := suite.setupIntlShippingAndLinehaulServiceItem() + + // PerUnitCents + paymentServiceItem.PaymentServiceItemParams[3].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err := pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to an int", models.ServiceItemParamNamePerUnitCents)) + + // ReferenceDate + paymentServiceItem.PaymentServiceItemParams[2].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to a time", models.ServiceItemParamNameReferenceDate)) + + // DistanceZip + paymentServiceItem.PaymentServiceItemParams[1].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to an int", models.ServiceItemParamNameDistanceZip)) + + // ContractCode + paymentServiceItem.PaymentServiceItemParams[0].ServiceItemParamKey.Type = models.ServiceItemParamTypeBoolean + _, _, err = pricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) + suite.Error(err) + suite.Contains(err.Error(), fmt.Sprintf("trying to convert %s to a string", models.ServiceItemParamNameContractCode)) + }) + + suite.Run("Price validation errors", func() { + + // No contract code + _, _, err := pricer.Price(suite.AppContextForTest(), "", islhTestRequestedPickupDate, islhTestDistance, islhTestWeight, islhTestPerUnitCents.Int()) + suite.Error(err) + suite.Equal("ContractCode is required", err.Error()) + + // No reference date + _, _, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, time.Time{}, islhTestDistance, islhTestWeight, islhTestPerUnitCents.Int()) + suite.Error(err) + suite.Equal("referenceDate is required", err.Error()) + + // No weight + _, _, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, islhTestRequestedPickupDate, islhTestDistance, 0, islhTestPerUnitCents.Int()) + suite.Error(err) + suite.Equal(fmt.Sprintf("weight must be at least %d", minIntlWeightHHG), err.Error()) + + // No per unit cents + _, _, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, islhTestRequestedPickupDate, islhTestDistance, islhTestWeight, 0) + suite.Error(err) + suite.Equal("PerUnitCents is required", err.Error()) + + }) +} + +func (suite *GHCRateEngineServiceSuite) setupIntlShippingAndLinehaulServiceItem() models.PaymentServiceItem { + contract := testdatagen.FetchOrMakeReContract(suite.DB(), testdatagen.Assertions{}) + startDate := time.Date(2018, time.January, 1, 12, 0, 0, 0, time.UTC) + endDate := time.Date(2018, time.December, 31, 12, 0, 0, 0, time.UTC) + testdatagen.FetchOrMakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + Contract: contract, + ContractID: contract.ID, + StartDate: startDate, + EndDate: endDate, + Escalation: 1.0, + EscalationCompounded: 1.0, + }, + }) + return factory.BuildPaymentServiceItemWithParams( + suite.DB(), + models.ReServiceCodeISLH, + []factory.CreatePaymentServiceItemParams{ + { + Key: models.ServiceItemParamNameContractCode, + KeyType: models.ServiceItemParamTypeString, + Value: contract.Code, + }, + { + Key: models.ServiceItemParamNameDistanceZip, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(islhTestDistance)), + }, + { + Key: models.ServiceItemParamNameReferenceDate, + KeyType: models.ServiceItemParamTypeDate, + Value: islhTestRequestedPickupDate.Format(DateParamFormat), + }, + { + Key: models.ServiceItemParamNamePerUnitCents, + KeyType: models.ServiceItemParamTypeInteger, + Value: fmt.Sprintf("%d", int(islhTestPerUnitCents)), + }, + { + Key: models.ServiceItemParamNameWeightBilled, + KeyType: models.ServiceItemParamTypeInteger, + Value: strconv.Itoa(islhTestWeight.Int()), + }, + }, nil, nil, + ) +} diff --git a/pkg/services/ghcrateengine/pricer_helpers_intl.go b/pkg/services/ghcrateengine/pricer_helpers_intl.go index 37f01ee9966..924dad55537 100644 --- a/pkg/services/ghcrateengine/pricer_helpers_intl.go +++ b/pkg/services/ghcrateengine/pricer_helpers_intl.go @@ -23,10 +23,13 @@ func priceIntlPackUnpack(appCtx appcontext.AppContext, packUnpackCode models.ReS if referenceDate.IsZero() { return 0, nil, errors.New("ReferenceDate is required") } + if perUnitCents == 0 { + return 0, nil, errors.New("PerUnitCents is required") + } isPeakPeriod := IsPeakPeriod(referenceDate) - contract, err := fetchContractsByContractCode(appCtx, contractCode) + contract, err := fetchContractByContractCode(appCtx, contractCode) if err != nil { return 0, nil, fmt.Errorf("could not find contract with code: %s: %w", contractCode, err) } diff --git a/pkg/services/ghcrateengine/pricer_helpers_intl_test.go b/pkg/services/ghcrateengine/pricer_helpers_intl_test.go new file mode 100644 index 00000000000..19539e4c976 --- /dev/null +++ b/pkg/services/ghcrateengine/pricer_helpers_intl_test.go @@ -0,0 +1,46 @@ +package ghcrateengine + +import ( + "time" + + "github.com/transcom/mymove/pkg/models" + "github.com/transcom/mymove/pkg/services" + "github.com/transcom/mymove/pkg/testdatagen" +) + +func (suite *GHCRateEngineServiceSuite) TestPriceIntlPackUnpack() { + suite.Run("success with IHPK", func() { + suite.setupIntlPackServiceItem() + totalCost, displayParams, err := priceIntlPackUnpack(suite.AppContextForTest(), models.ReServiceCodeIHPK, testdatagen.DefaultContractCode, ihpkTestRequestedPickupDate, ihpkTestWeight, ihpkTestPerUnitCents.Int()) + suite.NoError(err) + suite.Equal(ihpkTestTotalCost, totalCost) + + expectedParams := services.PricingDisplayParams{ + {Key: models.ServiceItemParamNameContractYearName, Value: ihpkTestContractYearName}, + {Key: models.ServiceItemParamNameEscalationCompounded, Value: FormatEscalation(ihpkTestEscalationCompounded)}, + {Key: models.ServiceItemParamNameIsPeak, Value: FormatBool(ihpkTestIsPeakPeriod)}, + {Key: models.ServiceItemParamNamePriceRateOrFactor, Value: FormatCents(ihpkTestPerUnitCents)}, + } + suite.validatePricerCreatedParams(expectedParams, displayParams) + }) + + suite.Run("Invalid parameters to Price", func() { + suite.setupIntlPackServiceItem() + _, _, err := priceIntlPackUnpack(suite.AppContextForTest(), models.ReServiceCodeDLH, testdatagen.DefaultContractCode, ihpkTestRequestedPickupDate, ihpkTestWeight, ihpkTestPerUnitCents.Int()) + suite.Error(err) + suite.Contains(err.Error(), "unsupported pack/unpack code") + + _, _, err = priceIntlPackUnpack(suite.AppContextForTest(), models.ReServiceCodeIHPK, "", ihpkTestRequestedPickupDate, ihpkTestWeight, ihpkTestPerUnitCents.Int()) + suite.Error(err) + suite.Contains(err.Error(), "ContractCode is required") + + _, _, err = priceIntlPackUnpack(suite.AppContextForTest(), models.ReServiceCodeIHPK, testdatagen.DefaultContractCode, time.Time{}, ihpkTestWeight, ihpkTestPerUnitCents.Int()) + suite.Error(err) + suite.Contains(err.Error(), "ReferenceDate is required") + + _, _, err = priceIntlPackUnpack(suite.AppContextForTest(), models.ReServiceCodeIHPK, testdatagen.DefaultContractCode, ihpkTestRequestedPickupDate, ihpkTestWeight, 0) + suite.Error(err) + suite.Contains(err.Error(), "PerUnitCents is required") + }) + +} diff --git a/pkg/services/ghcrateengine/pricer_helpers_test.go b/pkg/services/ghcrateengine/pricer_helpers_test.go index be3648927e2..06b9ec30044 100644 --- a/pkg/services/ghcrateengine/pricer_helpers_test.go +++ b/pkg/services/ghcrateengine/pricer_helpers_test.go @@ -529,7 +529,7 @@ func (suite *GHCRateEngineServiceSuite) Test_createPricerGeneratedParams() { _, err := createPricerGeneratedParams(suite.AppContextForTest(), subtestData.paymentServiceItem.ID, invalidParam) suite.Error(err) - suite.Contains(err.Error(), "Service item param key is not a pricer param") + suite.Contains(err.Error(), "service item param key is not a pricer param") }) suite.Run("errors if no PricingParms passed from the Pricer", func() { diff --git a/pkg/services/ghcrateengine/pricer_query_helpers.go b/pkg/services/ghcrateengine/pricer_query_helpers.go index 51acb06f9bd..84cde4fc64c 100644 --- a/pkg/services/ghcrateengine/pricer_query_helpers.go +++ b/pkg/services/ghcrateengine/pricer_query_helpers.go @@ -103,7 +103,7 @@ func fetchContractsByContractId(appCtx appcontext.AppContext, contractID uuid.UU return contracts, nil } -func fetchContractsByContractCode(appCtx appcontext.AppContext, contractCode string) (models.ReContract, error) { +func fetchContractByContractCode(appCtx appcontext.AppContext, contractCode string) (models.ReContract, error) { var contract models.ReContract err := appCtx.DB().Where("code = $1", contractCode).First(&contract) if err != nil { diff --git a/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx b/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx index 5aa3fdc0187..410e65506f1 100644 --- a/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx +++ b/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx @@ -145,7 +145,10 @@ const CreatePaymentRequestForm = ({ mtoServiceItem.reServiceCode === 'DOSFSC' || mtoServiceItem.reServiceCode === 'DDSHUT' || mtoServiceItem.reServiceCode === 'IHPK' || - mtoServiceItem.reServiceCode === 'IHUPK') && ( + mtoServiceItem.reServiceCode === 'IHUPK' || + mtoServiceItem.reServiceCode === 'ISLH' || + mtoServiceItem.reServiceCode === 'POEFSC' || + mtoServiceItem.reServiceCode === 'PODFSC') && ( { { id: '6', reServiceCode: 'DDFSIT', reServiceName: 'Domestic destination 1st day SIT' }, ], 2: [{ id: '5', reServiceCode: 'FSC' }], + 3: [ + { id: '7', reServiceCode: 'IHPK' }, + { id: '8', reServiceCode: 'IHUPK' }, + { id: '8', reServiceCode: 'ISLH' }, + { id: '8', reServiceCode: 'POEFSC' }, + ], }; it('renders the form', async () => { From c82e97c82e93477123ccaaa649cd42ee1956d85b Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 2 Jan 2025 22:28:29 +0000 Subject: [PATCH 42/52] updating address facotry to handle bogus postal code values when getting post region city ids --- pkg/factory/address_factory.go | 40 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/pkg/factory/address_factory.go b/pkg/factory/address_factory.go index d6b7dff6ce5..1ef93086ad8 100644 --- a/pkg/factory/address_factory.go +++ b/pkg/factory/address_factory.go @@ -1,7 +1,10 @@ package factory import ( + "database/sql" + "github.com/gobuffalo/pop/v6" + "github.com/gofrs/uuid" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/testdatagen" @@ -24,15 +27,17 @@ func BuildAddress(db *pop.Connection, customs []Customization, traits []Trait) m } // Create default Address + beverlyHillsUsprc := uuid.FromStringOrNil("3b9f0ae6-3b2b-44a6-9fcd-8ead346648c4") address := models.Address{ - StreetAddress1: "123 Any Street", - StreetAddress2: models.StringPointer("P.O. Box 12345"), - StreetAddress3: models.StringPointer("c/o Some Person"), - City: "Beverly Hills", - State: "CA", - PostalCode: "90210", - County: models.StringPointer("LOS ANGELES"), - IsOconus: models.BoolPointer(false), + StreetAddress1: "123 Any Street", + StreetAddress2: models.StringPointer("P.O. Box 12345"), + StreetAddress3: models.StringPointer("c/o Some Person"), + City: "Beverly Hills", + State: "CA", + PostalCode: "90210", + County: models.StringPointer("LOS ANGELES"), + IsOconus: models.BoolPointer(false), + UsPostRegionCityID: &beverlyHillsUsprc, } // Find/create the Country if customization is provided @@ -56,7 +61,7 @@ func BuildAddress(db *pop.Connection, customs []Customization, traits []Trait) m // Overwrite values with those from customizations testdatagen.MergeModels(&address, cAddress) - // This helps assign counties when the factory is called for seed data or tests + // This helps assign counties & us_post_region_cities_id values when the factory is called for seed data or tests // Additionally, also only run if not 90210. 90210's county is by default populated if db != nil && address.PostalCode != "90210" { county, err := models.FindCountyByZipCode(db, address.PostalCode) @@ -67,19 +72,18 @@ func BuildAddress(db *pop.Connection, customs []Customization, traits []Trait) m // The zip code successfully found a county address.County = county } - } else if db == nil && address.PostalCode != "90210" { - // If no db supplied, mark that - address.County = models.StringPointer("db nil when created") - } - - if db != nil { + // seeing if the postal code provided has a related us_post_region_cities_id usprc, err := models.FindByZipCode(db, address.PostalCode) - if err != nil { - return models.Address{} - } else { + if err != nil && err != sql.ErrNoRows { + address.UsPostRegionCityID = nil + address.UsPostRegionCity = nil + } else if usprc.ID != uuid.Nil { address.UsPostRegionCityID = &usprc.ID address.UsPostRegionCity = usprc } + } else if db == nil && address.PostalCode != "90210" { + // If no db supplied, mark that + address.County = models.StringPointer("db nil when created") } // If db is false, it's a stub. No need to create in database. From 5c81091f67693ad0c2199595f24b3cddfc9f82c9 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 3 Jan 2025 00:06:46 +0000 Subject: [PATCH 43/52] fixing some issues with tests and address factory --- pkg/factory/address_factory.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/factory/address_factory.go b/pkg/factory/address_factory.go index 1ef93086ad8..27d92999d00 100644 --- a/pkg/factory/address_factory.go +++ b/pkg/factory/address_factory.go @@ -72,7 +72,12 @@ func BuildAddress(db *pop.Connection, customs []Customization, traits []Trait) m // The zip code successfully found a county address.County = county } - // seeing if the postal code provided has a related us_post_region_cities_id + } else if db == nil && address.PostalCode != "90210" { + // If no db supplied, mark that + address.County = models.StringPointer("db nil when created") + } + + if db != nil && address.PostalCode != "90210" && cAddress.UsPostRegionCityID == nil { usprc, err := models.FindByZipCode(db, address.PostalCode) if err != nil && err != sql.ErrNoRows { address.UsPostRegionCityID = nil @@ -81,9 +86,6 @@ func BuildAddress(db *pop.Connection, customs []Customization, traits []Trait) m address.UsPostRegionCityID = &usprc.ID address.UsPostRegionCity = usprc } - } else if db == nil && address.PostalCode != "90210" { - // If no db supplied, mark that - address.County = models.StringPointer("db nil when created") } // If db is false, it's a stub. No need to create in database. From f39bfa372574e0e052ba52f32191c30c7a6c1740 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 3 Jan 2025 19:19:22 +0000 Subject: [PATCH 44/52] PR fix feedback --- ...aram_values_to_service_params_table.up.sql | 3 ++ .../per_unit_cents_lookup.go | 3 ++ .../per_unit_cents_lookup_test.go | 31 +++++++++++++ .../port_name_lookup.go | 2 +- .../port_name_lookup_test.go | 31 ++++++++++++- pkg/services/ghc_rate_engine.go | 2 +- .../intl_port_fuel_surcharge_pricer.go | 9 ++-- .../intl_port_fuel_surcharge_pricer_test.go | 14 +++--- .../CreatePaymentRequestForm.jsx | 43 ++++++++++--------- src/constants/serviceItems.js | 3 ++ 10 files changed, 103 insertions(+), 38 deletions(-) diff --git a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql index 63c1e404e50..859bbcb47b6 100644 --- a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql +++ b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql @@ -1,3 +1,6 @@ +-- dropping function that is not needed anymore +DROP FUNCTION IF EXISTS get_rate_area_id(UUID, UUID); + -- need to add in param keys for international shipments, this will be used to show breakdowns to the TIO INSERT INTO service_item_param_keys (id, key,description,type,origin,created_at,updated_at) VALUES ('d9ad3878-4b94-4722-bbaf-d4b8080f339d','PortName','Name of the port for an international shipment','STRING','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'), diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go index d2062218620..b339fbf43dd 100644 --- a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup.go @@ -17,6 +17,9 @@ type PerUnitCentsLookup struct { func (p PerUnitCentsLookup) lookup(appCtx appcontext.AppContext, s *ServiceItemParamKeyData) (string, error) { serviceID := p.ServiceItem.ReServiceID contractID := s.ContractID + if p.MTOShipment.RequestedPickupDate == nil { + return "", fmt.Errorf("requested pickup date is required for shipment with id: %s", p.MTOShipment.ID) + } switch p.ServiceItem.ReService.Code { case models.ReServiceCodeIHPK: diff --git a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go index 4d9ceab2512..9937f86217b 100644 --- a/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/per_unit_cents_lookup_test.go @@ -129,4 +129,35 @@ func (suite *ServiceParamValueLookupsSuite) TestPerUnitCentsLookup() { suite.Error(err) suite.Equal(perUnitCents, "") }) + + suite.Run("failure - no requested pickup date on shipment", func() { + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + mtoServiceItem = factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodeIHPK, + }, + }, + { + Model: models.MTOShipment{ + RequestedPickupDate: nil, + }, + }, + }, []factory.Trait{factory.GetTraitAvailableToPrimeMove}) + + mtoServiceItem.MTOShipment.RequestedPickupDate = nil + suite.MustSave(&mtoServiceItem.MTOShipment) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + perUnitCents, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.Error(err) + suite.Equal(perUnitCents, "") + }) } diff --git a/pkg/payment_request/service_param_value_lookups/port_name_lookup.go b/pkg/payment_request/service_param_value_lookups/port_name_lookup.go index 5013d3ae2c8..a925ceaa099 100644 --- a/pkg/payment_request/service_param_value_lookups/port_name_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/port_name_lookup.go @@ -21,7 +21,7 @@ func (p PortNameLookup) lookup(appCtx appcontext.AppContext, _ *ServiceItemParam } else if p.ServiceItem.POELocationID != nil { portLocationID = p.ServiceItem.POELocationID } else { - return "", nil + return "", fmt.Errorf("unable to find port location for service item id: %s", p.ServiceItem.ID) } var portLocation models.PortLocation err := appCtx.DB().Q(). diff --git a/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go b/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go index b0ccb4b2bfe..a16b174dc1c 100644 --- a/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go @@ -64,7 +64,7 @@ func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { portName, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) suite.FatalNoError(err) - suite.Equal(portName, "SEATTLE TACOMA INTL") + suite.Equal(portName, port.Port.PortName) }) suite.Run("success - returns PortName value for PODFSC", func() { @@ -82,6 +82,33 @@ func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { portName, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) suite.FatalNoError(err) - suite.Equal(portName, "PORTLAND INTL") + suite.Equal(portName, port.Port.PortName) + }) + + suite.Run("failure - no port value on service item", func() { + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + mtoServiceItem = factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: models.MTOServiceItem{ + POELocationID: nil, + }, + }, + }, []factory.Trait{factory.GetTraitAvailableToPrimeMove}) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + _, err = paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.Error(err) }) } diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 8b3ef07de0f..2247e3d7426 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -261,6 +261,6 @@ type IntlHHGUnpackPricer interface { // //go:generate mockery --name IntlPortFuelSurchargePricer type IntlPortFuelSurchargePricer interface { - Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, portName string) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go index 7d2c94e7096..3e6dcfe1bdd 100644 --- a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go @@ -23,7 +23,7 @@ func NewPortFuelSurchargePricer() services.IntlPortFuelSurchargePricer { return &portFuelSurchargePricer{} } -func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, portName string) (unit.Cents, services.PricingDisplayParams, error) { +func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents) (unit.Cents, services.PricingDisplayParams, error) { // Validate parameters if actualPickupDate.IsZero() { return 0, nil, errors.New("ActualPickupDate is required") @@ -40,9 +40,6 @@ func (p portFuelSurchargePricer) Price(_ appcontext.AppContext, actualPickupDate if eiaFuelPrice == 0 { return 0, nil, errors.New("EIAFuelPrice is required") } - if portName == "" { - return 0, nil, errors.New("PortName is required") - } fscPriceDifferenceInCents := (eiaFuelPrice - baseGHCDieselFuelPrice).Float64() / 1000.0 fscMultiplier := fscWeightBasedDistanceMultiplier * distance.Float64() @@ -99,10 +96,10 @@ func (p portFuelSurchargePricer) PriceUsingParams(appCtx appcontext.AppContext, return unit.Cents(0), nil, err } - portName, err := getParamString(params, models.ServiceItemParamNamePortName) + _, err = getParamString(params, models.ServiceItemParamNamePortName) if err != nil { return unit.Cents(0), nil, err } - return p.Price(appCtx, actualPickupDate, unit.Miles(distance), unit.Pound(weightBilled), fscWeightBasedDistanceMultiplier, unit.Millicents(eiaFuelPrice), portName) + return p.Price(appCtx, actualPickupDate, unit.Miles(distance), unit.Pound(weightBilled), fscWeightBasedDistanceMultiplier, unit.Millicents(eiaFuelPrice)) } diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go index 9c07773bdb8..fa660bd796d 100644 --- a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go @@ -45,7 +45,7 @@ func (suite *GHCRateEngineServiceSuite) TestIntlPortFuelSurchargePricer() { }) suite.Run("success without PaymentServiceItemParams", func() { - priceCents, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + priceCents, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice) suite.NoError(err) suite.Equal(intlPortFscPriceCents, priceCents) }) @@ -71,7 +71,7 @@ func (suite *GHCRateEngineServiceSuite) TestIntlPortFuelSurchargePricer() { }) suite.Run("FSC is negative if fuel price from EIA is below $2.50", func() { - priceCents, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, 242400, intlPortFscPortName) + priceCents, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, 242400) suite.NoError(err) suite.Equal(unit.Cents(-721), priceCents) }) @@ -79,27 +79,27 @@ func (suite *GHCRateEngineServiceSuite) TestIntlPortFuelSurchargePricer() { suite.Run("Price validation errors", func() { // No actual pickup date - _, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), time.Time{}, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + _, _, err := intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), time.Time{}, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice) suite.Error(err) suite.Equal("ActualPickupDate is required", err.Error()) // No distance - _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, unit.Miles(0), intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, unit.Miles(0), intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice) suite.Error(err) suite.Equal("Distance must be greater than 0", err.Error()) // No weight - _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, unit.Pound(0), intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice, intlPortFscPortName) + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, unit.Pound(0), intlPortFscWeightDistanceMultiplier, intlPortFscFuelPrice) suite.Error(err) suite.Equal(fmt.Sprintf("weight must be a minimum of %d", minDomesticWeight), err.Error()) // No weight based distance multiplier - _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, 0, intlPortFscFuelPrice, intlPortFscPortName) + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, 0, intlPortFscFuelPrice) suite.Error(err) suite.Equal("WeightBasedDistanceMultiplier is required", err.Error()) // No EIA fuel price - _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, 0, intlPortFscPortName) + _, _, err = intlPortFuelSurchargePricer.Price(suite.AppContextForTest(), intlPortFscActualPickupDate, intlPortFscTestDistance, intlPortFscTestWeight, intlPortFscWeightDistanceMultiplier, 0) suite.Error(err) suite.Equal("EIAFuelPrice is required", err.Error()) }) diff --git a/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx b/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx index 410e65506f1..d5b3f283829 100644 --- a/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx +++ b/src/components/PrimeUI/CreatePaymentRequestForm/CreatePaymentRequestForm.jsx @@ -18,6 +18,7 @@ import ServiceItem from 'components/PrimeUI/ServiceItem/ServiceItem'; import Shipment from 'components/PrimeUI/Shipment/Shipment'; import { DatePickerInput } from 'components/form/fields'; import TextField from 'components/form/fields/TextField/TextField'; +import { SERVICE_ITEM_CODES } from 'constants/serviceItems'; const CreatePaymentRequestForm = ({ initialValues, @@ -128,27 +129,27 @@ const CreatePaymentRequestForm = ({ /> )} - {(mtoServiceItem.reServiceCode === 'DLH' || - mtoServiceItem.reServiceCode === 'DSH' || - mtoServiceItem.reServiceCode === 'FSC' || - mtoServiceItem.reServiceCode === 'DUPK' || - mtoServiceItem.reServiceCode === 'DNPK' || - mtoServiceItem.reServiceCode === 'DOFSIT' || - mtoServiceItem.reServiceCode === 'DOPSIT' || - mtoServiceItem.reServiceCode === 'DOSHUT' || - mtoServiceItem.reServiceCode === 'DDFSIT' || - mtoServiceItem.reServiceCode === 'DDDSIT' || - mtoServiceItem.reServiceCode === 'DOP' || - mtoServiceItem.reServiceCode === 'DDP' || - mtoServiceItem.reServiceCode === 'DPK' || - mtoServiceItem.reServiceCode === 'DDSFSC' || - mtoServiceItem.reServiceCode === 'DOSFSC' || - mtoServiceItem.reServiceCode === 'DDSHUT' || - mtoServiceItem.reServiceCode === 'IHPK' || - mtoServiceItem.reServiceCode === 'IHUPK' || - mtoServiceItem.reServiceCode === 'ISLH' || - mtoServiceItem.reServiceCode === 'POEFSC' || - mtoServiceItem.reServiceCode === 'PODFSC') && ( + {(mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DLH || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DSH || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.FSC || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DUPK || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DNPK || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DOFSIT || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DOPSIT || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DOSHUT || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DDFSIT || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DDDSIT || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DOP || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DDP || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DPK || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DDSFSC || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DOSFSC || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.DDSHUT || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.IHPK || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.IHUPK || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.ISLH || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.POEFSC || + mtoServiceItem.reServiceCode === SERVICE_ITEM_CODES.PODFSC) && ( Date: Fri, 3 Jan 2025 20:21:47 +0000 Subject: [PATCH 45/52] mocks again --- .../mocks/IntlPortFuelSurchargePricer.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/services/mocks/IntlPortFuelSurchargePricer.go b/pkg/services/mocks/IntlPortFuelSurchargePricer.go index 48e396d017e..1780857c419 100644 --- a/pkg/services/mocks/IntlPortFuelSurchargePricer.go +++ b/pkg/services/mocks/IntlPortFuelSurchargePricer.go @@ -20,9 +20,9 @@ type IntlPortFuelSurchargePricer struct { mock.Mock } -// Price provides a mock function with given fields: appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName -func (_m *IntlPortFuelSurchargePricer) Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents, portName string) (unit.Cents, services.PricingDisplayParams, error) { - ret := _m.Called(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) +// Price provides a mock function with given fields: appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice +func (_m *IntlPortFuelSurchargePricer) Price(appCtx appcontext.AppContext, actualPickupDate time.Time, distance unit.Miles, weight unit.Pound, fscWeightBasedDistanceMultiplier float64, eiaFuelPrice unit.Millicents) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice) if len(ret) == 0 { panic("no return value specified for Price") @@ -31,25 +31,25 @@ func (_m *IntlPortFuelSurchargePricer) Price(appCtx appcontext.AppContext, actua var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) (unit.Cents, services.PricingDisplayParams, error)); ok { - return rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) unit.Cents); ok { - r0 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents) unit.Cents); ok { + r0 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) services.PricingDisplayParams); ok { - r1 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents) services.PricingDisplayParams); ok { + r1 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(services.PricingDisplayParams) } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents, string) error); ok { - r2 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice, portName) + if rf, ok := ret.Get(2).(func(appcontext.AppContext, time.Time, unit.Miles, unit.Pound, float64, unit.Millicents) error); ok { + r2 = rf(appCtx, actualPickupDate, distance, weight, fscWeightBasedDistanceMultiplier, eiaFuelPrice) } else { r2 = ret.Error(2) } From 114ee8e5c6974ec5c6bb2dce739b8eba00ad89d3 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 3 Jan 2025 21:49:10 +0000 Subject: [PATCH 46/52] updating prime docs --- pkg/gen/primeapi/embedded_spec.go | 4 +- .../payment_request/create_payment_request.go | 201 ++++++++++++++- .../payment_request/payment_request_client.go | 201 ++++++++++++++- swagger-def/prime.yaml | 171 ++++++++++++- swagger/prime.yaml | 233 ++++++++++++++++-- 5 files changed, 757 insertions(+), 53 deletions(-) diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index 52039d783cc..69ed189d17f 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -1063,7 +1063,7 @@ func init() { }, "/payment-requests": { "post": { - "description": "Creates a new instance of a paymentRequest and is assigned the status ` + "`" + `PENDING` + "`" + `.\nA move task order can have multiple payment requests, and\na final payment request can be marked using boolean ` + "`" + `isFinal` + "`" + `.\n\nIf a ` + "`" + `PENDING` + "`" + ` payment request is recalculated,\na new payment request is created and the original request is\nmarked with the status ` + "`" + `DEPRECATED` + "`" + `.\n\n**NOTE**: In order to create a payment request for most service items, the shipment *must*\nbe updated with the ` + "`" + `PrimeActualWeight` + "`" + ` value via [updateMTOShipment](#operation/updateMTOShipment).\n\n**FSC - Fuel Surcharge** service items require ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment.\n\nA service item can be on several payment requests in the case of partial payment requests and payments.\n\nIn the request, if no params are necessary, then just the ` + "`" + `serviceItem` + "`" + ` ` + "`" + `id` + "`" + ` is required. For example:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"isFinal\": false,\n \"moveTaskOrderID\": \"uuid\",\n \"serviceItems\": [\n {\n \"id\": \"uuid\",\n },\n {\n \"id\": \"uuid\",\n \"params\": [\n {\n \"key\": \"Service Item Parameter Name\",\n \"value\": \"Service Item Parameter Value\"\n }\n ]\n }\n ],\n \"pointOfContact\": \"string\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nSIT Service Items \u0026 Accepted Payment Request Parameters:\n---\nIf ` + "`" + `WeightBilled` + "`" + ` is not provided then the full shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) will be considered in the calculation.\n\n**NOTE**: Diversions have a unique calcuation for payment requests without a ` + "`" + `WeightBilled` + "`" + ` parameter.\n\nIf you created a payment request for a diversion and ` + "`" + `WeightBilled` + "`" + ` is not provided, then the following will be used in the calculation:\n- The lowest shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) found in the diverted shipment chain.\n- The lowest reweigh weight found in the diverted shipment chain.\n\nThe diverted shipment chain is created by referencing the ` + "`" + `diversion` + "`" + ` boolean, ` + "`" + `divertedFromShipmentId` + "`" + ` UUID, and matching destination to pickup addresses.\nIf the chain cannot be established it will fall back to the ` + "`" + `PrimeActualWeight` + "`" + ` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations.\nThe lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found.\n\n**DOFSIT - Domestic origin 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOASIT - Domestic origin add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOPSIT - Domestic origin SIT pickup**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOSHUT - Domestic origin shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDFSIT - Domestic destination 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDASIT - Domestic destination add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDDSIT - Domestic destination SIT delivery**\n*To create a paymentRequest for this service item, it must first have a final address set via [updateMTOServiceItem](#operation/updateMTOServiceItem).*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDSHUT - Domestic destination shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n---\n", + "description": "Creates a new instance of a paymentRequest and is assigned the status ` + "`" + `PENDING` + "`" + `.\nA move task order can have multiple payment requests, and\na final payment request can be marked using boolean ` + "`" + `isFinal` + "`" + `.\n\nIf a ` + "`" + `PENDING` + "`" + ` payment request is recalculated,\na new payment request is created and the original request is\nmarked with the status ` + "`" + `DEPRECATED` + "`" + `.\n\n**NOTE**: In order to create a payment request for most service items, the shipment *must*\nbe updated with the ` + "`" + `PrimeActualWeight` + "`" + ` value via [updateMTOShipment](#operation/updateMTOShipment).\n\nIf ` + "`" + `WeightBilled` + "`" + ` is not provided then the full shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) will be considered in the calculation.\n\n**NOTE**: Diversions have a unique calcuation for payment requests without a ` + "`" + `WeightBilled` + "`" + ` parameter.\n\nIf you created a payment request for a diversion and ` + "`" + `WeightBilled` + "`" + ` is not provided, then the following will be used in the calculation:\n- The lowest shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) found in the diverted shipment chain.\n- The lowest reweigh weight found in the diverted shipment chain.\n\nThe diverted shipment chain is created by referencing the ` + "`" + `diversion` + "`" + ` boolean, ` + "`" + `divertedFromShipmentId` + "`" + ` UUID, and matching destination to pickup addresses.\nIf the chain cannot be established it will fall back to the ` + "`" + `PrimeActualWeight` + "`" + ` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations.\nThe lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found.\n\nA service item can be on several payment requests in the case of partial payment requests and payments.\n\nIn the request, if no params are necessary, then just the ` + "`" + `serviceItem` + "`" + ` ` + "`" + `id` + "`" + ` is required. For example:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"isFinal\": false,\n \"moveTaskOrderID\": \"uuid\",\n \"serviceItems\": [\n {\n \"id\": \"uuid\",\n },\n {\n \"id\": \"uuid\",\n \"params\": [\n {\n \"key\": \"Service Item Parameter Name\",\n \"value\": \"Service Item Parameter Value\"\n }\n ]\n }\n ],\n \"pointOfContact\": \"string\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nDomestic Basic Service Items \u0026 Accepted Payment Request Parameters:\n---\n\n**DLH - Domestic Linehaul**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DSH - Domestic Shorthaul**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**FSC - Fuel Surcharge**\n**NOTE**: FSC requires ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment.\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DUPK - Domestic Unpacking**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DPK - Domestic Packing**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DNPK - Domestic NTS Packing**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DPK - Domestic Packing**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOP - Domestic Origin Price**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDP - Domestic Destination Price**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\nDomestic SIT Service Items \u0026 Accepted Payment Request Parameters:\n---\n\n**DOFSIT - Domestic origin 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOASIT - Domestic origin add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOPSIT - Domestic origin SIT pickup**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOSHUT - Domestic origin shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDFSIT - Domestic destination 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDASIT - Domestic destination add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDDSIT - Domestic destination SIT delivery**\n*To create a paymentRequest for this service item, it must first have a final address set via [updateMTOServiceItem](#operation/updateMTOServiceItem).*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDSHUT - Domestic destination shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n---\n\nInternational Basic Service Items \u0026 Accepted Payment Request Parameters:\n---\nJust like domestic shipments \u0026 service items, if ` + "`" + `WeightBilled` + "`" + ` is not provided then the full shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) will be considered in the calculation.\n**NOTE**: ` + "`" + `POEFSC` + "`" + ` \u0026 ` + "`" + `PODFSC` + "`" + ` service items must have a port associated on the service item in order to successfully add it to a payment request. To update the port of a service item, you must use the (#operation/updateMTOServiceItem) endpoint.\n\n**ISLH - International Shipping \u0026 Linehaul**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**IHPK - International HHG Pack**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**IHUPK - International HHG Unpack**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**POEFSC - International Port of Embarkation Fuel Surcharge**\n **NOTE**: POEFSC requires ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment \u0026 ` + "`" + `POELocation` + "`" + ` on the service item.\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**PODFSC - International Port of Debarkation Fuel Surcharge**\n**NOTE**: PODFSC requires ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment \u0026 ` + "`" + `PODLocation` + "`" + ` on the service item.\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n---\n", "consumes": [ "application/json" ], @@ -5921,7 +5921,7 @@ func init() { }, "/payment-requests": { "post": { - "description": "Creates a new instance of a paymentRequest and is assigned the status ` + "`" + `PENDING` + "`" + `.\nA move task order can have multiple payment requests, and\na final payment request can be marked using boolean ` + "`" + `isFinal` + "`" + `.\n\nIf a ` + "`" + `PENDING` + "`" + ` payment request is recalculated,\na new payment request is created and the original request is\nmarked with the status ` + "`" + `DEPRECATED` + "`" + `.\n\n**NOTE**: In order to create a payment request for most service items, the shipment *must*\nbe updated with the ` + "`" + `PrimeActualWeight` + "`" + ` value via [updateMTOShipment](#operation/updateMTOShipment).\n\n**FSC - Fuel Surcharge** service items require ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment.\n\nA service item can be on several payment requests in the case of partial payment requests and payments.\n\nIn the request, if no params are necessary, then just the ` + "`" + `serviceItem` + "`" + ` ` + "`" + `id` + "`" + ` is required. For example:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"isFinal\": false,\n \"moveTaskOrderID\": \"uuid\",\n \"serviceItems\": [\n {\n \"id\": \"uuid\",\n },\n {\n \"id\": \"uuid\",\n \"params\": [\n {\n \"key\": \"Service Item Parameter Name\",\n \"value\": \"Service Item Parameter Value\"\n }\n ]\n }\n ],\n \"pointOfContact\": \"string\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nSIT Service Items \u0026 Accepted Payment Request Parameters:\n---\nIf ` + "`" + `WeightBilled` + "`" + ` is not provided then the full shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) will be considered in the calculation.\n\n**NOTE**: Diversions have a unique calcuation for payment requests without a ` + "`" + `WeightBilled` + "`" + ` parameter.\n\nIf you created a payment request for a diversion and ` + "`" + `WeightBilled` + "`" + ` is not provided, then the following will be used in the calculation:\n- The lowest shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) found in the diverted shipment chain.\n- The lowest reweigh weight found in the diverted shipment chain.\n\nThe diverted shipment chain is created by referencing the ` + "`" + `diversion` + "`" + ` boolean, ` + "`" + `divertedFromShipmentId` + "`" + ` UUID, and matching destination to pickup addresses.\nIf the chain cannot be established it will fall back to the ` + "`" + `PrimeActualWeight` + "`" + ` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations.\nThe lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found.\n\n**DOFSIT - Domestic origin 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOASIT - Domestic origin add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOPSIT - Domestic origin SIT pickup**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOSHUT - Domestic origin shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDFSIT - Domestic destination 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDASIT - Domestic destination add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDDSIT - Domestic destination SIT delivery**\n*To create a paymentRequest for this service item, it must first have a final address set via [updateMTOServiceItem](#operation/updateMTOServiceItem).*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDSHUT - Domestic destination shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n---\n", + "description": "Creates a new instance of a paymentRequest and is assigned the status ` + "`" + `PENDING` + "`" + `.\nA move task order can have multiple payment requests, and\na final payment request can be marked using boolean ` + "`" + `isFinal` + "`" + `.\n\nIf a ` + "`" + `PENDING` + "`" + ` payment request is recalculated,\na new payment request is created and the original request is\nmarked with the status ` + "`" + `DEPRECATED` + "`" + `.\n\n**NOTE**: In order to create a payment request for most service items, the shipment *must*\nbe updated with the ` + "`" + `PrimeActualWeight` + "`" + ` value via [updateMTOShipment](#operation/updateMTOShipment).\n\nIf ` + "`" + `WeightBilled` + "`" + ` is not provided then the full shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) will be considered in the calculation.\n\n**NOTE**: Diversions have a unique calcuation for payment requests without a ` + "`" + `WeightBilled` + "`" + ` parameter.\n\nIf you created a payment request for a diversion and ` + "`" + `WeightBilled` + "`" + ` is not provided, then the following will be used in the calculation:\n- The lowest shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) found in the diverted shipment chain.\n- The lowest reweigh weight found in the diverted shipment chain.\n\nThe diverted shipment chain is created by referencing the ` + "`" + `diversion` + "`" + ` boolean, ` + "`" + `divertedFromShipmentId` + "`" + ` UUID, and matching destination to pickup addresses.\nIf the chain cannot be established it will fall back to the ` + "`" + `PrimeActualWeight` + "`" + ` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations.\nThe lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found.\n\nA service item can be on several payment requests in the case of partial payment requests and payments.\n\nIn the request, if no params are necessary, then just the ` + "`" + `serviceItem` + "`" + ` ` + "`" + `id` + "`" + ` is required. For example:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"isFinal\": false,\n \"moveTaskOrderID\": \"uuid\",\n \"serviceItems\": [\n {\n \"id\": \"uuid\",\n },\n {\n \"id\": \"uuid\",\n \"params\": [\n {\n \"key\": \"Service Item Parameter Name\",\n \"value\": \"Service Item Parameter Value\"\n }\n ]\n }\n ],\n \"pointOfContact\": \"string\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nDomestic Basic Service Items \u0026 Accepted Payment Request Parameters:\n---\n\n**DLH - Domestic Linehaul**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DSH - Domestic Shorthaul**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**FSC - Fuel Surcharge**\n**NOTE**: FSC requires ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment.\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DUPK - Domestic Unpacking**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DPK - Domestic Packing**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DNPK - Domestic NTS Packing**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DPK - Domestic Packing**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOP - Domestic Origin Price**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDP - Domestic Destination Price**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\nDomestic SIT Service Items \u0026 Accepted Payment Request Parameters:\n---\n\n**DOFSIT - Domestic origin 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOASIT - Domestic origin add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOPSIT - Domestic origin SIT pickup**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DOSHUT - Domestic origin shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDFSIT - Domestic destination 1st day SIT**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDASIT - Domestic destination add'l SIT** *(SITPaymentRequestStart \u0026 SITPaymentRequestEnd are **REQUIRED**)*\n*To create a paymentRequest for this service item, the ` + "`" + `SITPaymentRequestStart` + "`" + ` and ` + "`" + `SITPaymentRequestEnd` + "`" + ` dates must not overlap previously requested SIT dates.*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n },\n {\n \"key\": \"SITPaymentRequestStart\",\n \"value\": \"date\"\n },\n {\n \"key\": \"SITPaymentRequestEnd\",\n \"value\": \"date\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDDSIT - Domestic destination SIT delivery**\n*To create a paymentRequest for this service item, it must first have a final address set via [updateMTOServiceItem](#operation/updateMTOServiceItem).*\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**DDSHUT - Domestic destination shuttle service**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n---\n\nInternational Basic Service Items \u0026 Accepted Payment Request Parameters:\n---\nJust like domestic shipments \u0026 service items, if ` + "`" + `WeightBilled` + "`" + ` is not provided then the full shipment weight (` + "`" + `PrimeActualWeight` + "`" + `) will be considered in the calculation.\n**NOTE**: ` + "`" + `POEFSC` + "`" + ` \u0026 ` + "`" + `PODFSC` + "`" + ` service items must have a port associated on the service item in order to successfully add it to a payment request. To update the port of a service item, you must use the (#operation/updateMTOServiceItem) endpoint.\n\n**ISLH - International Shipping \u0026 Linehaul**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**IHPK - International HHG Pack**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**IHUPK - International HHG Unpack**\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**POEFSC - International Port of Embarkation Fuel Surcharge**\n **NOTE**: POEFSC requires ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment \u0026 ` + "`" + `POELocation` + "`" + ` on the service item.\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n\n**PODFSC - International Port of Debarkation Fuel Surcharge**\n**NOTE**: PODFSC requires ` + "`" + `ActualPickupDate` + "`" + ` to be updated on the shipment \u0026 ` + "`" + `PODLocation` + "`" + ` on the service item.\n` + "`" + `` + "`" + `` + "`" + `json\n \"params\": [\n {\n \"key\": \"WeightBilled\",\n \"value\": \"integer\"\n }\n ]\n` + "`" + `` + "`" + `` + "`" + `\n---\n", "consumes": [ "application/json" ], diff --git a/pkg/gen/primeapi/primeoperations/payment_request/create_payment_request.go b/pkg/gen/primeapi/primeoperations/payment_request/create_payment_request.go index 1e98d93abe7..d1ca6a38ab8 100644 --- a/pkg/gen/primeapi/primeoperations/payment_request/create_payment_request.go +++ b/pkg/gen/primeapi/primeoperations/payment_request/create_payment_request.go @@ -45,7 +45,17 @@ marked with the status `DEPRECATED`. **NOTE**: In order to create a payment request for most service items, the shipment *must* be updated with the `PrimeActualWeight` value via [updateMTOShipment](#operation/updateMTOShipment). -**FSC - Fuel Surcharge** service items require `ActualPickupDate` to be updated on the shipment. +If `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. + +**NOTE**: Diversions have a unique calcuation for payment requests without a `WeightBilled` parameter. + +If you created a payment request for a diversion and `WeightBilled` is not provided, then the following will be used in the calculation: +- The lowest shipment weight (`PrimeActualWeight`) found in the diverted shipment chain. +- The lowest reweigh weight found in the diverted shipment chain. + +The diverted shipment chain is created by referencing the `diversion` boolean, `divertedFromShipmentId` UUID, and matching destination to pickup addresses. +If the chain cannot be established it will fall back to the `PrimeActualWeight` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations. +The lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found. A service item can be on several payment requests in the case of partial payment requests and payments. @@ -74,19 +84,120 @@ In the request, if no params are necessary, then just the `serviceItem` `id` is ``` -SIT Service Items & Accepted Payment Request Parameters: +Domestic Basic Service Items & Accepted Payment Request Parameters: --- -If `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. -**NOTE**: Diversions have a unique calcuation for payment requests without a `WeightBilled` parameter. +**DLH - Domestic Linehaul** +```json -If you created a payment request for a diversion and `WeightBilled` is not provided, then the following will be used in the calculation: -- The lowest shipment weight (`PrimeActualWeight`) found in the diverted shipment chain. -- The lowest reweigh weight found in the diverted shipment chain. + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] -The diverted shipment chain is created by referencing the `diversion` boolean, `divertedFromShipmentId` UUID, and matching destination to pickup addresses. -If the chain cannot be established it will fall back to the `PrimeActualWeight` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations. -The lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found. +``` + +**DSH - Domestic Shorthaul** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**FSC - Fuel Surcharge** +**NOTE**: FSC requires `ActualPickupDate` to be updated on the shipment. +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DUPK - Domestic Unpacking** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DPK - Domestic Packing** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DNPK - Domestic NTS Packing** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DPK - Domestic Packing** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DOP - Domestic Origin Price** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DDP - Domestic Destination Price** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +Domestic SIT Service Items & Accepted Payment Request Parameters: +--- **DOFSIT - Domestic origin 1st day SIT** ```json @@ -201,6 +312,76 @@ The lowest weight found is the true shipment weight, and thus we search the chai } ] +``` +--- + +International Basic Service Items & Accepted Payment Request Parameters: +--- +Just like domestic shipments & service items, if `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. +**NOTE**: `POEFSC` & `PODFSC` service items must have a port associated on the service item in order to successfully add it to a payment request. To update the port of a service item, you must use the (#operation/updateMTOServiceItem) endpoint. + +**ISLH - International Shipping & Linehaul** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**IHPK - International HHG Pack** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**IHUPK - International HHG Unpack** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**POEFSC - International Port of Embarkation Fuel Surcharge** + + **NOTE**: POEFSC requires `ActualPickupDate` to be updated on the shipment & `POELocation` on the service item. + +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**PODFSC - International Port of Debarkation Fuel Surcharge** +**NOTE**: PODFSC requires `ActualPickupDate` to be updated on the shipment & `PODLocation` on the service item. +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` --- */ diff --git a/pkg/gen/primeclient/payment_request/payment_request_client.go b/pkg/gen/primeclient/payment_request/payment_request_client.go index 82eae72610e..b10b46d87cf 100644 --- a/pkg/gen/primeclient/payment_request/payment_request_client.go +++ b/pkg/gen/primeclient/payment_request/payment_request_client.go @@ -52,7 +52,17 @@ marked with the status `DEPRECATED`. **NOTE**: In order to create a payment request for most service items, the shipment *must* be updated with the `PrimeActualWeight` value via [updateMTOShipment](#operation/updateMTOShipment). -**FSC - Fuel Surcharge** service items require `ActualPickupDate` to be updated on the shipment. +If `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. + +**NOTE**: Diversions have a unique calcuation for payment requests without a `WeightBilled` parameter. + +If you created a payment request for a diversion and `WeightBilled` is not provided, then the following will be used in the calculation: +- The lowest shipment weight (`PrimeActualWeight`) found in the diverted shipment chain. +- The lowest reweigh weight found in the diverted shipment chain. + +The diverted shipment chain is created by referencing the `diversion` boolean, `divertedFromShipmentId` UUID, and matching destination to pickup addresses. +If the chain cannot be established it will fall back to the `PrimeActualWeight` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations. +The lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found. A service item can be on several payment requests in the case of partial payment requests and payments. @@ -81,19 +91,120 @@ In the request, if no params are necessary, then just the `serviceItem` `id` is ``` -SIT Service Items & Accepted Payment Request Parameters: +Domestic Basic Service Items & Accepted Payment Request Parameters: --- -If `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. -**NOTE**: Diversions have a unique calcuation for payment requests without a `WeightBilled` parameter. +**DLH - Domestic Linehaul** +```json -If you created a payment request for a diversion and `WeightBilled` is not provided, then the following will be used in the calculation: -- The lowest shipment weight (`PrimeActualWeight`) found in the diverted shipment chain. -- The lowest reweigh weight found in the diverted shipment chain. + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] -The diverted shipment chain is created by referencing the `diversion` boolean, `divertedFromShipmentId` UUID, and matching destination to pickup addresses. -If the chain cannot be established it will fall back to the `PrimeActualWeight` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations. -The lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found. +``` + +**DSH - Domestic Shorthaul** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**FSC - Fuel Surcharge** +**NOTE**: FSC requires `ActualPickupDate` to be updated on the shipment. +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DUPK - Domestic Unpacking** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DPK - Domestic Packing** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DNPK - Domestic NTS Packing** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DPK - Domestic Packing** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DOP - Domestic Origin Price** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**DDP - Domestic Destination Price** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +Domestic SIT Service Items & Accepted Payment Request Parameters: +--- **DOFSIT - Domestic origin 1st day SIT** ```json @@ -208,6 +319,76 @@ The lowest weight found is the true shipment weight, and thus we search the chai } ] +``` +--- + +International Basic Service Items & Accepted Payment Request Parameters: +--- +Just like domestic shipments & service items, if `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. +**NOTE**: `POEFSC` & `PODFSC` service items must have a port associated on the service item in order to successfully add it to a payment request. To update the port of a service item, you must use the (#operation/updateMTOServiceItem) endpoint. + +**ISLH - International Shipping & Linehaul** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**IHPK - International HHG Pack** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**IHUPK - International HHG Unpack** +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**POEFSC - International Port of Embarkation Fuel Surcharge** + + **NOTE**: POEFSC requires `ActualPickupDate` to be updated on the shipment & `POELocation` on the service item. + +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + +``` + +**PODFSC - International Port of Debarkation Fuel Surcharge** +**NOTE**: PODFSC requires `ActualPickupDate` to be updated on the shipment & `PODLocation` on the service item. +```json + + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` --- */ diff --git a/swagger-def/prime.yaml b/swagger-def/prime.yaml index 5fcb6cdd5e3..61f19f25a93 100644 --- a/swagger-def/prime.yaml +++ b/swagger-def/prime.yaml @@ -952,7 +952,17 @@ paths: **NOTE**: In order to create a payment request for most service items, the shipment *must* be updated with the `PrimeActualWeight` value via [updateMTOShipment](#operation/updateMTOShipment). - **FSC - Fuel Surcharge** service items require `ActualPickupDate` to be updated on the shipment. + If `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. + + **NOTE**: Diversions have a unique calcuation for payment requests without a `WeightBilled` parameter. + + If you created a payment request for a diversion and `WeightBilled` is not provided, then the following will be used in the calculation: + - The lowest shipment weight (`PrimeActualWeight`) found in the diverted shipment chain. + - The lowest reweigh weight found in the diverted shipment chain. + + The diverted shipment chain is created by referencing the `diversion` boolean, `divertedFromShipmentId` UUID, and matching destination to pickup addresses. + If the chain cannot be established it will fall back to the `PrimeActualWeight` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations. + The lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found. A service item can be on several payment requests in the case of partial payment requests and payments. @@ -979,19 +989,102 @@ paths: } ``` - SIT Service Items & Accepted Payment Request Parameters: + Domestic Basic Service Items & Accepted Payment Request Parameters: --- - If `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. - **NOTE**: Diversions have a unique calcuation for payment requests without a `WeightBilled` parameter. + **DLH - Domestic Linehaul** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` - If you created a payment request for a diversion and `WeightBilled` is not provided, then the following will be used in the calculation: - - The lowest shipment weight (`PrimeActualWeight`) found in the diverted shipment chain. - - The lowest reweigh weight found in the diverted shipment chain. + **DSH - Domestic Shorthaul** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` - The diverted shipment chain is created by referencing the `diversion` boolean, `divertedFromShipmentId` UUID, and matching destination to pickup addresses. - If the chain cannot be established it will fall back to the `PrimeActualWeight` of the current shipment. This is utilized because diverted shipments are all one single shipment, but going to different locations. - The lowest weight found is the true shipment weight, and thus we search the chain of shipments for the lowest weight found. + **FSC - Fuel Surcharge** + **NOTE**: FSC requires `ActualPickupDate` to be updated on the shipment. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **DUPK - Domestic Unpacking** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **DPK - Domestic Packing** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **DNPK - Domestic NTS Packing** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **DPK - Domestic Packing** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **DOP - Domestic Origin Price** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **DDP - Domestic Destination Price** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + Domestic SIT Service Items & Accepted Payment Request Parameters: + --- **DOFSIT - Domestic origin 1st day SIT** ```json @@ -1092,6 +1185,64 @@ paths: ] ``` --- + + International Basic Service Items & Accepted Payment Request Parameters: + --- + Just like domestic shipments & service items, if `WeightBilled` is not provided then the full shipment weight (`PrimeActualWeight`) will be considered in the calculation. + **NOTE**: `POEFSC` & `PODFSC` service items must have a port associated on the service item in order to successfully add it to a payment request. To update the port of a service item, you must use the (#operation/updateMTOServiceItem) endpoint. + + **ISLH - International Shipping & Linehaul** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **IHPK - International HHG Pack** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **IHUPK - International HHG Unpack** + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **POEFSC - International Port of Embarkation Fuel Surcharge** + **NOTE**: POEFSC requires `ActualPickupDate` to be updated on the shipment & `POELocation` on the service item. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + **PODFSC - International Port of Debarkation Fuel Surcharge** + **NOTE**: PODFSC requires `ActualPickupDate` to be updated on the shipment & `PODLocation` on the service item. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + --- operationId: createPaymentRequest tags: - paymentRequest diff --git a/swagger/prime.yaml b/swagger/prime.yaml index 83ef52b06c7..2f7082e307b 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -1214,8 +1214,34 @@ paths: [updateMTOShipment](#operation/updateMTOShipment). - **FSC - Fuel Surcharge** service items require `ActualPickupDate` to be - updated on the shipment. + If `WeightBilled` is not provided then the full shipment weight + (`PrimeActualWeight`) will be considered in the calculation. + + + **NOTE**: Diversions have a unique calcuation for payment requests + without a `WeightBilled` parameter. + + + If you created a payment request for a diversion and `WeightBilled` is + not provided, then the following will be used in the calculation: + + - The lowest shipment weight (`PrimeActualWeight`) found in the diverted + shipment chain. + + - The lowest reweigh weight found in the diverted shipment chain. + + + The diverted shipment chain is created by referencing the `diversion` + boolean, `divertedFromShipmentId` UUID, and matching destination to + pickup addresses. + + If the chain cannot be established it will fall back to the + `PrimeActualWeight` of the current shipment. This is utilized because + diverted shipments are all one single shipment, but going to different + locations. + + The lowest weight found is the true shipment weight, and thus we search + the chain of shipments for the lowest weight found. A service item can be on several payment requests in the case of partial @@ -1250,38 +1276,124 @@ paths: ``` - SIT Service Items & Accepted Payment Request Parameters: + Domestic Basic Service Items & Accepted Payment Request Parameters: --- - If `WeightBilled` is not provided then the full shipment weight - (`PrimeActualWeight`) will be considered in the calculation. + **DLH - Domestic Linehaul** - **NOTE**: Diversions have a unique calcuation for payment requests - without a `WeightBilled` parameter. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` - If you created a payment request for a diversion and `WeightBilled` is - not provided, then the following will be used in the calculation: + **DSH - Domestic Shorthaul** - - The lowest shipment weight (`PrimeActualWeight`) found in the diverted - shipment chain. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` - - The lowest reweigh weight found in the diverted shipment chain. + **FSC - Fuel Surcharge** - The diverted shipment chain is created by referencing the `diversion` - boolean, `divertedFromShipmentId` UUID, and matching destination to - pickup addresses. + **NOTE**: FSC requires `ActualPickupDate` to be updated on the shipment. - If the chain cannot be established it will fall back to the - `PrimeActualWeight` of the current shipment. This is utilized because - diverted shipments are all one single shipment, but going to different - locations. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **DUPK - Domestic Unpacking** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **DPK - Domestic Packing** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **DNPK - Domestic NTS Packing** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **DPK - Domestic Packing** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` - The lowest weight found is the true shipment weight, and thus we search - the chain of shipments for the lowest weight found. + + **DOP - Domestic Origin Price** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **DDP - Domestic Destination Price** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + Domestic SIT Service Items & Accepted Payment Request Parameters: + + --- **DOFSIT - Domestic origin 1st day SIT** @@ -1410,6 +1522,85 @@ paths: ``` --- + + + International Basic Service Items & Accepted Payment Request Parameters: + + --- + + Just like domestic shipments & service items, if `WeightBilled` is not + provided then the full shipment weight (`PrimeActualWeight`) will be + considered in the calculation. + + **NOTE**: `POEFSC` & `PODFSC` service items must have a port associated + on the service item in order to successfully add it to a payment + request. To update the port of a service item, you must use the + (#operation/updateMTOServiceItem) endpoint. + + + **ISLH - International Shipping & Linehaul** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **IHPK - International HHG Pack** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **IHUPK - International HHG Unpack** + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **POEFSC - International Port of Embarkation Fuel Surcharge** + **NOTE**: POEFSC requires `ActualPickupDate` to be updated on the shipment & `POELocation` on the service item. + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + + **PODFSC - International Port of Debarkation Fuel Surcharge** + + **NOTE**: PODFSC requires `ActualPickupDate` to be updated on the + shipment & `PODLocation` on the service item. + + ```json + "params": [ + { + "key": "WeightBilled", + "value": "integer" + } + ] + ``` + + --- operationId: createPaymentRequest tags: - paymentRequest From 4890576da4e3179d2e4073491ef8ca81e2869374 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Mon, 6 Jan 2025 16:56:13 +0000 Subject: [PATCH 47/52] adding logic to use port ZIP for international shipments and ZIP lookups --- ...aram_values_to_service_params_table.up.sql | 2 +- pkg/models/service_item_param_key.go | 8 +-- .../distance_zip_lookup.go | 24 ++++++- .../distance_zip_lookup_test.go | 62 +++++++++++++++++++ ...port_name_lookup.go => port_zip_lookup.go} | 15 ++--- ...lookup_test.go => port_zip_lookup_test.go} | 18 +++--- .../service_param_value_lookups.go | 4 +- .../service_param_value_lookups_test.go | 8 +++ .../intl_port_fuel_surcharge_pricer.go | 2 +- .../intl_port_fuel_surcharge_pricer_test.go | 6 +- 10 files changed, 120 insertions(+), 29 deletions(-) rename pkg/payment_request/service_param_value_lookups/{port_name_lookup.go => port_zip_lookup.go} (50%) rename pkg/payment_request/service_param_value_lookups/{port_name_lookup_test.go => port_zip_lookup_test.go} (83%) diff --git a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql index 859bbcb47b6..1186b75a7b2 100644 --- a/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql +++ b/migrations/app/schema/20241226173330_add_intl_param_values_to_service_params_table.up.sql @@ -3,7 +3,7 @@ DROP FUNCTION IF EXISTS get_rate_area_id(UUID, UUID); -- need to add in param keys for international shipments, this will be used to show breakdowns to the TIO INSERT INTO service_item_param_keys (id, key,description,type,origin,created_at,updated_at) VALUES - ('d9ad3878-4b94-4722-bbaf-d4b8080f339d','PortName','Name of the port for an international shipment','STRING','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'), + ('d9ad3878-4b94-4722-bbaf-d4b8080f339d','PortZip','ZIP of the port for an international shipment pickup or destination port','STRING','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'), ('597bb77e-0ce7-4ba2-9624-24300962625f','PerUnitCents','Per unit cents for a service item','INTEGER','SYSTEM','2024-12-26 15:55:50.041957','2024-12-26 15:55:50.041957'); -- inserting params for PODFSC diff --git a/pkg/models/service_item_param_key.go b/pkg/models/service_item_param_key.go index 868c6785b55..0c637cc7d92 100644 --- a/pkg/models/service_item_param_key.go +++ b/pkg/models/service_item_param_key.go @@ -63,8 +63,8 @@ const ( ServiceItemParamNameNumberDaysSIT ServiceItemParamName = "NumberDaysSIT" // ServiceItemParamNamePerUnitCents is the param key name PerUnitCents ServiceItemParamNamePerUnitCents ServiceItemParamName = "PerUnitCents" - // ServiceItemParamNamePortName is the param key name PortName - ServiceItemParamNamePortName ServiceItemParamName = "PortName" + // ServiceItemParamNamePortZip is the param key name PortZip + ServiceItemParamNamePortZip ServiceItemParamName = "PortZip" // ServiceItemParamNamePriceAreaDest is the param key name PriceAreaDest ServiceItemParamNamePriceAreaDest ServiceItemParamName = "PriceAreaDest" // ServiceItemParamNamePriceAreaIntlDest is the param key name PriceAreaIntlDest @@ -280,7 +280,7 @@ var ValidServiceItemParamNames = []ServiceItemParamName{ ServiceItemParamNameUncappedRequestTotal, ServiceItemParamNameLockedPriceCents, ServiceItemParamNamePerUnitCents, - ServiceItemParamNamePortName, + ServiceItemParamNamePortZip, } // ValidServiceItemParamNameStrings lists all valid service item param key names @@ -356,7 +356,7 @@ var ValidServiceItemParamNameStrings = []string{ string(ServiceItemParamNameUncappedRequestTotal), string(ServiceItemParamNameLockedPriceCents), string(ServiceItemParamNamePerUnitCents), - string(ServiceItemParamNamePortName), + string(ServiceItemParamNamePortZip), } // ValidServiceItemParamTypes lists all valid service item param types diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go index 7b70c559d1d..7f05aa59ee9 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup.go @@ -49,6 +49,25 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service // Now calculate the distance between zips pickupZip := r.PickupAddress.PostalCode destinationZip := r.DestinationAddress.PostalCode + + // if the shipment is international, we need to change the respective ZIP to use the port ZIP and not the address ZIP + if mtoShipment.MarketCode == models.MarketCodeInternational { + portZip, portType, err := models.GetPortLocationInfoForShipment(appCtx.DB(), *mtoShipmentID) + if err != nil { + return "", err + } + if portZip != nil && portType != nil { + // if the port type is POEFSC this means the shipment is CONUS -> OCONUS (pickup -> port) + // if the port type is PODFSC this means the shipment is OCONUS -> CONUS (port -> destination) + if *portType == models.ReServiceCodePOEFSC.String() { + destinationZip = *portZip + } else if *portType == models.ReServiceCodePODFSC.String() { + pickupZip = *portZip + } + } else { + return "", apperror.NewNotFoundError(*mtoShipmentID, "looking for port ZIP for shipment") + } + } errorMsgForPickupZip := fmt.Sprintf("Shipment must have valid pickup zipcode. Received: %s", pickupZip) errorMsgForDestinationZip := fmt.Sprintf("Shipment must have valid destination zipcode. Received: %s", destinationZip) if len(pickupZip) < 5 { @@ -91,14 +110,15 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service } } - if mtoShipment.Distance != nil && mtoShipment.ShipmentType != models.MTOShipmentTypePPM { + internationalShipment := mtoShipment.MarketCode == models.MarketCodeInternational + if mtoShipment.Distance != nil && mtoShipment.ShipmentType != models.MTOShipmentTypePPM && !internationalShipment { return strconv.Itoa(mtoShipment.Distance.Int()), nil } if pickupZip == destinationZip { distanceMiles = 1 } else { - distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false, false) + distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false, internationalShipment) if err != nil { return "", err } diff --git a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go index f40692f2f1c..f4fa18c8790 100644 --- a/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/distance_zip_lookup_test.go @@ -63,6 +63,68 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() { suite.Equal(unit.Miles(defaultZipDistance), *mtoShipment.Distance) }) + suite.Run("Calculate transit zip distance for international shipment with port data", func() { + testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ + ReContractYear: models.ReContractYear{ + StartDate: time.Now().Add(-24 * time.Hour), + EndDate: time.Now().Add(24 * time.Hour), + }, + }) + portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "SEA", + }, + }, + }, nil) + mtoServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: models.Address{ + PostalCode: "74133", + }, + Type: &factory.Addresses.PickupAddress, + }, + { + Model: models.MTOServiceItem{ + POELocationID: &portLocation.ID, + }, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + }, []factory.Trait{ + factory.GetTraitAvailableToPrimeMove, + }) + + paymentRequest := factory.BuildPaymentRequest(suite.DB(), []factory.Customization{ + { + Model: mtoServiceItem.MoveTaskOrder, + LinkOnly: true, + }, + }, nil) + + paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, paymentRequest.ID, paymentRequest.MoveTaskOrderID, nil) + suite.FatalNoError(err) + + distanceStr, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + suite.FatalNoError(err) + expected := strconv.Itoa(defaultInternationalZipDistance) + suite.Equal(expected, distanceStr) + + var mtoShipment models.MTOShipment + err = suite.DB().Find(&mtoShipment, mtoServiceItem.MTOShipmentID) + suite.NoError(err) + + suite.Equal(unit.Miles(defaultInternationalZipDistance), *mtoShipment.Distance) + }) + suite.Run("Calculate zip distance lookup without a saved service item", func() { ppmShipment := factory.BuildPPMShipment(suite.DB(), nil, nil) diff --git a/pkg/payment_request/service_param_value_lookups/port_name_lookup.go b/pkg/payment_request/service_param_value_lookups/port_zip_lookup.go similarity index 50% rename from pkg/payment_request/service_param_value_lookups/port_name_lookup.go rename to pkg/payment_request/service_param_value_lookups/port_zip_lookup.go index a925ceaa099..3ea8be94315 100644 --- a/pkg/payment_request/service_param_value_lookups/port_name_lookup.go +++ b/pkg/payment_request/service_param_value_lookups/port_zip_lookup.go @@ -9,26 +9,27 @@ import ( "github.com/transcom/mymove/pkg/models" ) -// PortNameLookup does lookup on the shipment and finds the port name -type PortNameLookup struct { +// PortZipLookup does lookup on the shipment and finds the port zip +// The mileage calculated is from port <-> pickup/destination so this value is important +type PortZipLookup struct { ServiceItem models.MTOServiceItem } -func (p PortNameLookup) lookup(appCtx appcontext.AppContext, _ *ServiceItemParamKeyData) (string, error) { +func (p PortZipLookup) lookup(appCtx appcontext.AppContext, _ *ServiceItemParamKeyData) (string, error) { var portLocationID *uuid.UUID if p.ServiceItem.PODLocationID != nil { portLocationID = p.ServiceItem.PODLocationID } else if p.ServiceItem.POELocationID != nil { portLocationID = p.ServiceItem.POELocationID } else { - return "", fmt.Errorf("unable to find port location for service item id: %s", p.ServiceItem.ID) + return "", fmt.Errorf("unable to find port zip for service item id: %s", p.ServiceItem.ID) } var portLocation models.PortLocation err := appCtx.DB().Q(). - EagerPreload("Port"). + EagerPreload("UsPostRegionCity"). Where("id = $1", portLocationID).First(&portLocation) if err != nil { - return "", fmt.Errorf("unable to find port location with id %s", portLocationID) + return "", fmt.Errorf("unable to find port zip with id %s", portLocationID) } - return portLocation.Port.PortName, nil + return portLocation.UsPostRegionCity.UsprZipID, nil } diff --git a/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go b/pkg/payment_request/service_param_value_lookups/port_zip_lookup_test.go similarity index 83% rename from pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go rename to pkg/payment_request/service_param_value_lookups/port_zip_lookup_test.go index a16b174dc1c..4410ba8e198 100644 --- a/pkg/payment_request/service_param_value_lookups/port_name_lookup_test.go +++ b/pkg/payment_request/service_param_value_lookups/port_zip_lookup_test.go @@ -10,8 +10,8 @@ import ( "github.com/transcom/mymove/pkg/testdatagen" ) -func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { - key := models.ServiceItemParamNamePortName +func (suite *ServiceParamValueLookupsSuite) TestPortZipLookup() { + key := models.ServiceItemParamNamePortZip var mtoServiceItem models.MTOServiceItem setupTestData := func(serviceCode models.ReServiceCode, portID uuid.UUID) { testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ @@ -49,7 +49,7 @@ func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { } } - suite.Run("success - returns PortName value for POEFSC", func() { + suite.Run("success - returns PortZip value for POEFSC", func() { port := factory.FetchPortLocation(suite.DB(), []factory.Customization{ { Model: models.Port{ @@ -62,12 +62,12 @@ func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) suite.FatalNoError(err) - portName, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + portZip, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) suite.FatalNoError(err) - suite.Equal(portName, port.Port.PortName) + suite.Equal(portZip, port.UsPostRegionCity.UsprZipID) }) - suite.Run("success - returns PortName value for PODFSC", func() { + suite.Run("success - returns PortZip value for PODFSC", func() { port := factory.FetchPortLocation(suite.DB(), []factory.Customization{ { Model: models.Port{ @@ -80,12 +80,12 @@ func (suite *ServiceParamValueLookupsSuite) TestPortNameLookup() { paramLookup, err := ServiceParamLookupInitialize(suite.AppContextForTest(), suite.planner, mtoServiceItem, uuid.Must(uuid.NewV4()), mtoServiceItem.MoveTaskOrderID, nil) suite.FatalNoError(err) - portName, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) + portZip, err := paramLookup.ServiceParamValue(suite.AppContextForTest(), key) suite.FatalNoError(err) - suite.Equal(portName, port.Port.PortName) + suite.Equal(portZip, port.UsPostRegionCity.UsprZipID) }) - suite.Run("failure - no port value on service item", func() { + suite.Run("failure - no port zip on service item", func() { testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{ ReContractYear: models.ReContractYear{ StartDate: time.Now().Add(-24 * time.Hour), diff --git a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go index c3669e5cb41..33775af842b 100644 --- a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go +++ b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go @@ -87,7 +87,7 @@ var ServiceItemParamsWithLookups = []models.ServiceItemParamName{ models.ServiceItemParamNameStandaloneCrateCap, models.ServiceItemParamNameLockedPriceCents, models.ServiceItemParamNamePerUnitCents, - models.ServiceItemParamNamePortName, + models.ServiceItemParamNamePortZip, } // ServiceParamLookupInitialize initializes service parameter lookup @@ -439,7 +439,7 @@ func InitializeLookups(appCtx appcontext.AppContext, shipment models.MTOShipment MTOShipment: shipment, } - lookups[models.ServiceItemParamNamePortName] = PortNameLookup{ + lookups[models.ServiceItemParamNamePortZip] = PortZipLookup{ ServiceItem: serviceItem, } diff --git a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go index 1c9138e51ee..7b8307f147c 100644 --- a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go +++ b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups_test.go @@ -29,6 +29,7 @@ import ( ) const defaultZipDistance = 1234 +const defaultInternationalZipDistance = 1800 type ServiceParamValueLookupsSuite struct { *testingsuite.PopTestSuite @@ -49,6 +50,13 @@ func TestServiceParamValueLookupsSuite(t *testing.T) { false, false, ).Return(defaultZipDistance, nil) + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + true, + ).Return(defaultInternationalZipDistance, nil) ts := &ServiceParamValueLookupsSuite{ PopTestSuite: testingsuite.NewPopTestSuite(testingsuite.CurrentPackage(), testingsuite.WithPerTestTransaction()), diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go index 3e6dcfe1bdd..e970f29a1c0 100644 --- a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer.go @@ -96,7 +96,7 @@ func (p portFuelSurchargePricer) PriceUsingParams(appCtx appcontext.AppContext, return unit.Cents(0), nil, err } - _, err = getParamString(params, models.ServiceItemParamNamePortName) + _, err = getParamString(params, models.ServiceItemParamNamePortZip) if err != nil { return unit.Cents(0), nil, err } diff --git a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go index fa660bd796d..ce64f248c22 100644 --- a/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go +++ b/pkg/services/ghcrateengine/intl_port_fuel_surcharge_pricer_test.go @@ -20,7 +20,7 @@ const ( intlPortFscWeightDistanceMultiplier = float64(0.000417) intlPortFscFuelPrice = unit.Millicents(281400) intlPortFscPriceCents = unit.Cents(2980) - intlPortFscPortName = "PORTLAND INTL" + intlPortFscPortZip = "99505" ) var intlPortFscActualPickupDate = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) @@ -186,9 +186,9 @@ func (suite *GHCRateEngineServiceSuite) setupPortFuelSurchargeServiceItem() mode Value: fmt.Sprintf("%d", int(intlPortFscFuelPrice)), }, { - Key: models.ServiceItemParamNamePortName, + Key: models.ServiceItemParamNamePortZip, KeyType: models.ServiceItemParamTypeString, - Value: intlPortFscPortName, + Value: intlPortFscPortZip, }, }, nil, nil, ) From 24cf97188d8e910911fa109cc57712a1a2a3657e Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 22:39:44 +0000 Subject: [PATCH 48/52] initial commit, functonality added, tests added --- migrations/app/migrations_manifest.txt | 1 + ...4_add_destination_gbloc_db_function.up.sql | 85 ++++++++++++++++ pkg/gen/ghcapi/embedded_spec.go | 10 ++ pkg/gen/ghcmessages/address.go | 20 ++++ pkg/gen/internalapi/embedded_spec.go | 10 ++ pkg/gen/internalmessages/address.go | 20 ++++ pkg/gen/pptasapi/embedded_spec.go | 10 ++ pkg/gen/pptasmessages/address.go | 20 ++++ pkg/gen/primeapi/embedded_spec.go | 10 ++ pkg/gen/primemessages/address.go | 20 ++++ pkg/gen/primev2api/embedded_spec.go | 10 ++ pkg/gen/primev2messages/address.go | 20 ++++ pkg/gen/primev3api/embedded_spec.go | 10 ++ pkg/gen/primev3messages/address.go | 20 ++++ .../primeapiv3/payloads/model_to_payload.go | 21 ++-- .../payloads/model_to_payload_test.go | 53 +++++----- pkg/models/address.go | 1 + pkg/models/mto_shipments.go | 20 ++++ pkg/models/mto_shipments_test.go | 97 +++++++++++++++++++ .../move_task_order_fetcher.go | 12 +++ .../move_task_order_fetcher_test.go | 57 +++++++++++ swagger-def/definitions/Address.yaml | 4 + swagger/ghc.yaml | 4 + swagger/internal.yaml | 4 + swagger/pptas.yaml | 4 + swagger/prime.yaml | 4 + swagger/prime_v2.yaml | 4 + swagger/prime_v3.yaml | 4 + 28 files changed, 521 insertions(+), 34 deletions(-) create mode 100644 migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 32afaa072da..222544bddb1 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1058,6 +1058,7 @@ 20241217180136_add_AK_zips_to_zip3_distances.up.sql 20241218201833_add_PPPO_BASE_ELIZABETH.up.sql 20241220171035_add_additional_AK_zips_to_zip3_distances.up.sql +20241220213134_add_destination_gbloc_db_function.up.sql 20241227153723_remove_empty_string_emplid_values.up.sql 20241227202424_insert_transportation_offices_camp_pendelton.up.sql 20241230190638_remove_AK_zips_from_zip3.up.sql diff --git a/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql b/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql new file mode 100644 index 00000000000..bd7d9b1db5d --- /dev/null +++ b/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql @@ -0,0 +1,85 @@ +-- this function will handle getting the destination GBLOC associated with a shipment's destination address +-- this only applies to OCONUS destination addresses on a shipment, but this also checks domestic shipments +CREATE OR REPLACE FUNCTION get_destination_gbloc_for_shipment(shipment_id UUID) +RETURNS TEXT AS $$ +DECLARE + service_member_affiliation TEXT; + zip TEXT; + gbloc_result TEXT; + alaska_zone_ii BOOLEAN; + market_code TEXT; +BEGIN + -- get the shipment's market_code + SELECT ms.market_code + INTO market_code + FROM mto_shipments ms + WHERE ms.id = shipment_id; + + -- if it's a domestic shipment, use postal_code_to_gblocs + IF market_code = 'd' THEN + SELECT upc.uspr_zip_id + INTO zip + FROM addresses a + JOIN us_post_region_cities upc ON a.us_post_region_cities_id = upc.id + WHERE a.id = (SELECT destination_address_id FROM mto_shipments WHERE id = shipment_id); + + SELECT gbloc + INTO gbloc_result + FROM postal_code_to_gblocs + WHERE postal_code = zip + LIMIT 1; + + IF gbloc_result IS NULL THEN + RETURN NULL; + END IF; + + RETURN gbloc_result; + + ELSEIF market_code = 'i' THEN + -- if it's 'i' then we need to check for some exceptions + SELECT sm.affiliation + INTO service_member_affiliation + FROM service_members sm + JOIN orders o ON o.service_member_id = sm.id + JOIN moves m ON m.orders_id = o.id + JOIN mto_shipments ms ON ms.move_id = m.id + WHERE ms.id = shipment_id; + + SELECT upc.uspr_zip_id + INTO zip + FROM addresses a + JOIN us_post_region_cities upc ON a.us_post_region_cities_id = upc.id + WHERE a.id = (SELECT destination_address_id FROM mto_shipments WHERE id = shipment_id); + + -- check if the postal code (uspr_zip_id) is in Alaska Zone II + SELECT EXISTS ( + SELECT 1 + FROM re_oconus_rate_areas ro + JOIN re_rate_areas ra ON ro.rate_area_id = ra.id + JOIN us_post_region_cities upc ON upc.id = ro.us_post_region_cities_id + WHERE upc.uspr_zip_id = zip + AND ra.code = 'US8190100' -- Alaska Zone II Code + ) + INTO alaska_zone_ii; + + -- if the service member is USAF or USSF and the address is in Alaska Zone II, return 'MBFL' + IF (service_member_affiliation = 'AIR_FORCE' OR service_member_affiliation = 'SPACE_FORCE') AND alaska_zone_ii THEN + RETURN 'MBFL'; + END IF; + + -- for all other branches except USMC, return the gbloc from the postal_code_to_gbloc table based on the zip + SELECT gbloc + INTO gbloc_result + FROM postal_code_to_gblocs + WHERE postal_code = zip + LIMIT 1; + + IF gbloc_result IS NULL THEN + RETURN NULL; + END IF; + + RETURN gbloc_result; + END IF; + +END; +$$ LANGUAGE plpgsql; diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 361f666c222..3b8e14d3e66 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -6403,6 +6403,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true @@ -23143,6 +23148,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true diff --git a/pkg/gen/ghcmessages/address.go b/pkg/gen/ghcmessages/address.go index 47148e32cf7..42bd1d8d69e 100644 --- a/pkg/gen/ghcmessages/address.go +++ b/pkg/gen/ghcmessages/address.go @@ -36,6 +36,10 @@ type Address struct { // Example: LOS ANGELES County *string `json:"county,omitempty"` + // destination gbloc + // Pattern: ^[A-Z]{4}$ + DestinationGbloc *string `json:"destinationGbloc,omitempty"` + // e tag // Read Only: true ETag string `json:"eTag,omitempty"` @@ -91,6 +95,10 @@ func (m *Address) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateDestinationGbloc(formats); err != nil { + res = append(res, err) + } + if err := m.validateID(formats); err != nil { res = append(res, err) } @@ -138,6 +146,18 @@ func (m *Address) validateCountry(formats strfmt.Registry) error { return nil } +func (m *Address) validateDestinationGbloc(formats strfmt.Registry) error { + if swag.IsZero(m.DestinationGbloc) { // not required + return nil + } + + if err := validate.Pattern("destinationGbloc", "body", *m.DestinationGbloc, `^[A-Z]{4}$`); err != nil { + return err + } + + return nil +} + func (m *Address) validateID(formats strfmt.Registry) error { if swag.IsZero(m.ID) { // not required return nil diff --git a/pkg/gen/internalapi/embedded_spec.go b/pkg/gen/internalapi/embedded_spec.go index c1351734062..53aee4aa8cf 100644 --- a/pkg/gen/internalapi/embedded_spec.go +++ b/pkg/gen/internalapi/embedded_spec.go @@ -3363,6 +3363,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true @@ -12482,6 +12487,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true diff --git a/pkg/gen/internalmessages/address.go b/pkg/gen/internalmessages/address.go index 529cc0d7110..733df1c0680 100644 --- a/pkg/gen/internalmessages/address.go +++ b/pkg/gen/internalmessages/address.go @@ -36,6 +36,10 @@ type Address struct { // Example: LOS ANGELES County *string `json:"county,omitempty"` + // destination gbloc + // Pattern: ^[A-Z]{4}$ + DestinationGbloc *string `json:"destinationGbloc,omitempty"` + // e tag // Read Only: true ETag string `json:"eTag,omitempty"` @@ -91,6 +95,10 @@ func (m *Address) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateDestinationGbloc(formats); err != nil { + res = append(res, err) + } + if err := m.validateID(formats); err != nil { res = append(res, err) } @@ -138,6 +146,18 @@ func (m *Address) validateCountry(formats strfmt.Registry) error { return nil } +func (m *Address) validateDestinationGbloc(formats strfmt.Registry) error { + if swag.IsZero(m.DestinationGbloc) { // not required + return nil + } + + if err := validate.Pattern("destinationGbloc", "body", *m.DestinationGbloc, `^[A-Z]{4}$`); err != nil { + return err + } + + return nil +} + func (m *Address) validateID(formats strfmt.Registry) error { if swag.IsZero(m.ID) { // not required return nil diff --git a/pkg/gen/pptasapi/embedded_spec.go b/pkg/gen/pptasapi/embedded_spec.go index 1757ac556cc..fc54f37df09 100644 --- a/pkg/gen/pptasapi/embedded_spec.go +++ b/pkg/gen/pptasapi/embedded_spec.go @@ -114,6 +114,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true @@ -1008,6 +1013,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true diff --git a/pkg/gen/pptasmessages/address.go b/pkg/gen/pptasmessages/address.go index 1e53ba6d230..0e5a9af985a 100644 --- a/pkg/gen/pptasmessages/address.go +++ b/pkg/gen/pptasmessages/address.go @@ -36,6 +36,10 @@ type Address struct { // Example: LOS ANGELES County *string `json:"county,omitempty"` + // destination gbloc + // Pattern: ^[A-Z]{4}$ + DestinationGbloc *string `json:"destinationGbloc,omitempty"` + // e tag // Read Only: true ETag string `json:"eTag,omitempty"` @@ -91,6 +95,10 @@ func (m *Address) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateDestinationGbloc(formats); err != nil { + res = append(res, err) + } + if err := m.validateID(formats); err != nil { res = append(res, err) } @@ -138,6 +146,18 @@ func (m *Address) validateCountry(formats strfmt.Registry) error { return nil } +func (m *Address) validateDestinationGbloc(formats strfmt.Registry) error { + if swag.IsZero(m.DestinationGbloc) { // not required + return nil + } + + if err := validate.Pattern("destinationGbloc", "body", *m.DestinationGbloc, `^[A-Z]{4}$`); err != nil { + return err + } + + return nil +} + func (m *Address) validateID(formats strfmt.Registry) error { if swag.IsZero(m.ID) { // not required return nil diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index 52039d783cc..9076c994d00 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -1214,6 +1214,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true @@ -6108,6 +6113,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true diff --git a/pkg/gen/primemessages/address.go b/pkg/gen/primemessages/address.go index 2fe5ba87adb..4ff5b6f7932 100644 --- a/pkg/gen/primemessages/address.go +++ b/pkg/gen/primemessages/address.go @@ -36,6 +36,10 @@ type Address struct { // Example: LOS ANGELES County *string `json:"county,omitempty"` + // destination gbloc + // Pattern: ^[A-Z]{4}$ + DestinationGbloc *string `json:"destinationGbloc,omitempty"` + // e tag // Read Only: true ETag string `json:"eTag,omitempty"` @@ -91,6 +95,10 @@ func (m *Address) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateDestinationGbloc(formats); err != nil { + res = append(res, err) + } + if err := m.validateID(formats); err != nil { res = append(res, err) } @@ -138,6 +146,18 @@ func (m *Address) validateCountry(formats strfmt.Registry) error { return nil } +func (m *Address) validateDestinationGbloc(formats strfmt.Registry) error { + if swag.IsZero(m.DestinationGbloc) { // not required + return nil + } + + if err := validate.Pattern("destinationGbloc", "body", *m.DestinationGbloc, `^[A-Z]{4}$`); err != nil { + return err + } + + return nil +} + func (m *Address) validateID(formats strfmt.Registry) error { if swag.IsZero(m.ID) { // not required return nil diff --git a/pkg/gen/primev2api/embedded_spec.go b/pkg/gen/primev2api/embedded_spec.go index f0468e10884..f6ffd9298ba 100644 --- a/pkg/gen/primev2api/embedded_spec.go +++ b/pkg/gen/primev2api/embedded_spec.go @@ -399,6 +399,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true @@ -4006,6 +4011,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true diff --git a/pkg/gen/primev2messages/address.go b/pkg/gen/primev2messages/address.go index 631419ea719..2f1631a297c 100644 --- a/pkg/gen/primev2messages/address.go +++ b/pkg/gen/primev2messages/address.go @@ -36,6 +36,10 @@ type Address struct { // Example: LOS ANGELES County *string `json:"county,omitempty"` + // destination gbloc + // Pattern: ^[A-Z]{4}$ + DestinationGbloc *string `json:"destinationGbloc,omitempty"` + // e tag // Read Only: true ETag string `json:"eTag,omitempty"` @@ -91,6 +95,10 @@ func (m *Address) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateDestinationGbloc(formats); err != nil { + res = append(res, err) + } + if err := m.validateID(formats); err != nil { res = append(res, err) } @@ -138,6 +146,18 @@ func (m *Address) validateCountry(formats strfmt.Registry) error { return nil } +func (m *Address) validateDestinationGbloc(formats strfmt.Registry) error { + if swag.IsZero(m.DestinationGbloc) { // not required + return nil + } + + if err := validate.Pattern("destinationGbloc", "body", *m.DestinationGbloc, `^[A-Z]{4}$`); err != nil { + return err + } + + return nil +} + func (m *Address) validateID(formats strfmt.Registry) error { if swag.IsZero(m.ID) { // not required return nil diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index 22f6c879b42..e788d625932 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -405,6 +405,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true @@ -4697,6 +4702,11 @@ func init() { "x-nullable": true, "example": "LOS ANGELES" }, + "destinationGbloc": { + "type": "string", + "pattern": "^[A-Z]{4}$", + "x-nullable": true + }, "eTag": { "type": "string", "readOnly": true diff --git a/pkg/gen/primev3messages/address.go b/pkg/gen/primev3messages/address.go index edffd06b01c..43fbf3bc550 100644 --- a/pkg/gen/primev3messages/address.go +++ b/pkg/gen/primev3messages/address.go @@ -36,6 +36,10 @@ type Address struct { // Example: LOS ANGELES County *string `json:"county,omitempty"` + // destination gbloc + // Pattern: ^[A-Z]{4}$ + DestinationGbloc *string `json:"destinationGbloc,omitempty"` + // e tag // Read Only: true ETag string `json:"eTag,omitempty"` @@ -91,6 +95,10 @@ func (m *Address) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateDestinationGbloc(formats); err != nil { + res = append(res, err) + } + if err := m.validateID(formats); err != nil { res = append(res, err) } @@ -138,6 +146,18 @@ func (m *Address) validateCountry(formats strfmt.Registry) error { return nil } +func (m *Address) validateDestinationGbloc(formats strfmt.Registry) error { + if swag.IsZero(m.DestinationGbloc) { // not required + return nil + } + + if err := validate.Pattern("destinationGbloc", "body", *m.DestinationGbloc, `^[A-Z]{4}$`); err != nil { + return err + } + + return nil +} + func (m *Address) validateID(formats strfmt.Registry) error { if swag.IsZero(m.ID) { // not required return nil diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload.go b/pkg/handlers/primeapiv3/payloads/model_to_payload.go index 4676e9b3d47..2b93dd3480f 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload.go @@ -231,16 +231,17 @@ func Address(address *models.Address) *primev3messages.Address { return nil } return &primev3messages.Address{ - ID: strfmt.UUID(address.ID.String()), - StreetAddress1: &address.StreetAddress1, - StreetAddress2: address.StreetAddress2, - StreetAddress3: address.StreetAddress3, - City: &address.City, - State: &address.State, - PostalCode: &address.PostalCode, - Country: Country(address.Country), - ETag: etag.GenerateEtag(address.UpdatedAt), - County: address.County, + ID: strfmt.UUID(address.ID.String()), + StreetAddress1: &address.StreetAddress1, + StreetAddress2: address.StreetAddress2, + StreetAddress3: address.StreetAddress3, + City: &address.City, + State: &address.State, + PostalCode: &address.PostalCode, + Country: Country(address.Country), + ETag: etag.GenerateEtag(address.UpdatedAt), + County: address.County, + DestinationGbloc: address.DestinationGbloc, } } diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go b/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go index e6de847b908..8ef4396aa1d 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go @@ -144,12 +144,13 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { PostalCode: fairbanksAlaskaPostalCode, }, DestinationAddress: &models.Address{ - StreetAddress1: "123 Main St", - StreetAddress2: &streetAddress2, - StreetAddress3: &streetAddress3, - City: "Anchorage", - State: "AK", - PostalCode: anchorageAlaskaPostalCode, + StreetAddress1: "123 Main St", + StreetAddress2: &streetAddress2, + StreetAddress3: &streetAddress3, + City: "Anchorage", + State: "AK", + PostalCode: anchorageAlaskaPostalCode, + DestinationGbloc: models.StringPointer("JEAT"), }, }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ @@ -162,12 +163,13 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { PostalCode: wasillaAlaskaPostalCode, }, DestinationAddress: &models.Address{ - StreetAddress1: "123 Main St", - StreetAddress2: &streetAddress2, - StreetAddress3: &streetAddress3, - City: "Wasilla", - State: "AK", - PostalCode: wasillaAlaskaPostalCode, + StreetAddress1: "123 Main St", + StreetAddress2: &streetAddress2, + StreetAddress3: &streetAddress3, + City: "Wasilla", + State: "AK", + PostalCode: wasillaAlaskaPostalCode, + DestinationGbloc: models.StringPointer("JEAT"), }, }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ @@ -231,20 +233,22 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ PickupAddress: &models.Address{ - StreetAddress1: "123 Main St", - StreetAddress2: &streetAddress2, - StreetAddress3: &streetAddress3, - City: "Beverly Hills", - State: "CA", - PostalCode: "90210", + StreetAddress1: "123 Main St", + StreetAddress2: &streetAddress2, + StreetAddress3: &streetAddress3, + City: "Beverly Hills", + State: "CA", + PostalCode: "90210", + DestinationGbloc: models.StringPointer("JEAT"), }, DestinationAddress: &models.Address{ - StreetAddress1: "123 Main St", - StreetAddress2: &streetAddress2, - StreetAddress3: &streetAddress3, - City: "Beverly Hills", - State: "CA", - PostalCode: "90210", + StreetAddress1: "123 Main St", + StreetAddress2: &streetAddress2, + StreetAddress3: &streetAddress3, + City: "Beverly Hills", + State: "CA", + PostalCode: "90210", + DestinationGbloc: models.StringPointer("JEAT"), }, }) @@ -351,6 +355,7 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { } else { suite.NotNil(shipment.PickupAddress) suite.NotNil(shipment.DestinationAddress) + suite.NotNil(shipment.DestinationAddress.DestinationGbloc) if slices.Contains(expectedAlaskaPostalCodes, *shipment.PickupAddress.PostalCode) { ra, contains := shipmentPostalCodeRateAreaLookupMap[*shipment.PickupAddress.PostalCode] suite.True(contains) diff --git a/pkg/models/address.go b/pkg/models/address.go index e683f7771ab..6042ae53960 100644 --- a/pkg/models/address.go +++ b/pkg/models/address.go @@ -34,6 +34,7 @@ type Address struct { IsOconus *bool `json:"is_oconus" db:"is_oconus"` UsPostRegionCityID *uuid.UUID `json:"us_post_region_cities_id" db:"us_post_region_cities_id"` UsPostRegionCity *UsPostRegionCity `belongs_to:"us_post_region_cities" fk_id:"us_post_region_cities_id"` + DestinationGbloc *string `db:"-"` } // TableName overrides the table name used by Pop. diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index 9b914f98198..783188addaa 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -415,6 +415,26 @@ func UpdateEstimatedPricingForShipmentBasicServiceItems(db *pop.Connection, ship return nil } +// GetDestinationGblocForShipment gets the GBLOC associated with the shipment's destination address +// there are certain exceptions for OCONUS addresses in Alaska Zone II based on affiliation +func GetDestinationGblocForShipment(db *pop.Connection, shipmentID uuid.UUID) (*string, error) { + var gbloc *string + + err := db.RawQuery("SELECT * FROM get_destination_gbloc_for_shipment($1)", shipmentID). + First(&gbloc) + + if err != nil && err != sql.ErrNoRows { + return nil, fmt.Errorf("error fetching destination gbloc for shipment ID: %s with error %w", shipmentID, err) + } + + // return the ZIP code and port type, or nil if not found + if gbloc != nil { + return gbloc, nil + } + + return nil, nil +} + // Returns a Shipment for a given id func FetchShipmentByID(db *pop.Connection, shipmentID uuid.UUID) (*MTOShipment, error) { var mtoShipment MTOShipment diff --git a/pkg/models/mto_shipments_test.go b/pkg/models/mto_shipments_test.go index 0af9121e013..1b92fbb7035 100644 --- a/pkg/models/mto_shipments_test.go +++ b/pkg/models/mto_shipments_test.go @@ -339,3 +339,100 @@ func (suite *ModelSuite) TestFindShipmentByID() { suite.Equal(models.ErrFetchNotFound, err) }) } + +func (suite *ModelSuite) TestGetDestinationGblocForShipment() { + suite.Run("success - get GBLOC for USAF in AK Zone II", func() { + // Create a USAF move in Alaska Zone II + // this is a hard coded uuid that is a us_post_region_cities_id within AK Zone II + // this should always return MBFL + zone2UUID, err := uuid.FromString("66768964-e0de-41f3-b9be-7ef32e4ae2b4") + suite.FatalNoError(err) + airForce := models.AffiliationAIRFORCE + postalCode := "99501" + + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: postalCode, + UsPostRegionCityID: &zone2UUID, + }, + }, + }, nil) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &airForce, + }, + }, + }, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: destinationAddress, + LinkOnly: true, + }, + }, nil) + + gbloc, err := models.GetDestinationGblocForShipment(suite.DB(), shipment.ID) + suite.NoError(err) + suite.NotNil(gbloc) + suite.Equal(*gbloc, "MBFL") + }) + suite.Run("success - get GBLOC for Army in AK Zone II", func() { + // Create an ARMY move in Alaska Zone II + zone2UUID, err := uuid.FromString("66768964-e0de-41f3-b9be-7ef32e4ae2b4") + suite.FatalNoError(err) + army := models.AffiliationARMY + postalCode := "99501" + // since we truncate the test db, we need to add the postal_code_to_gbloc value + factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), "99744", "JEAT") + + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: postalCode, + UsPostRegionCityID: &zone2UUID, + }, + }, + }, nil) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &army, + }, + }, + }, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: destinationAddress, + LinkOnly: true, + }, + }, nil) + + gbloc, err := models.GetDestinationGblocForShipment(suite.DB(), shipment.ID) + suite.NoError(err) + suite.NotNil(gbloc) + suite.Equal(*gbloc, "JEAT") + }) +} diff --git a/pkg/services/move_task_order/move_task_order_fetcher.go b/pkg/services/move_task_order/move_task_order_fetcher.go index b63f5960290..b41d6bc9176 100644 --- a/pkg/services/move_task_order/move_task_order_fetcher.go +++ b/pkg/services/move_task_order/move_task_order_fetcher.go @@ -278,6 +278,18 @@ func (f moveTaskOrderFetcher) FetchMoveTaskOrder(appCtx appcontext.AppContext, s return &models.Move{}, apperror.NewQueryError("MobileHomeShipment", loadErrMH, "") } } + // we need to get the destination GBLOC associated with a shipment's destination address + // USMC always goes to the USMC GBLOC + if mto.MTOShipments[i].DestinationAddress != nil { + if *mto.Orders.ServiceMember.Affiliation == models.AffiliationMARINES { + *mto.MTOShipments[i].DestinationAddress.DestinationGbloc = "USMC" + } else { + mto.MTOShipments[i].DestinationAddress.DestinationGbloc, err = models.GetDestinationGblocForShipment(appCtx.DB(), mto.MTOShipments[i].ID) + if err != nil { + return &models.Move{}, apperror.NewQueryError("Error getting shipment GBLOC", err, "") + } + } + } filteredShipments = append(filteredShipments, mto.MTOShipments[i]) } mto.MTOShipments = filteredShipments diff --git a/pkg/services/move_task_order/move_task_order_fetcher_test.go b/pkg/services/move_task_order/move_task_order_fetcher_test.go index 9ba9f7a8ba2..fb59f8209f3 100644 --- a/pkg/services/move_task_order/move_task_order_fetcher_test.go +++ b/pkg/services/move_task_order/move_task_order_fetcher_test.go @@ -344,6 +344,63 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderFetcher() { } }) + suite.Run("Success with Prime available move, returns destination GBLOC in shipment dest address", func() { + zone2UUID, err := uuid.FromString("66768964-e0de-41f3-b9be-7ef32e4ae2b4") + suite.FatalNoError(err) + army := models.AffiliationARMY + postalCode := "99501" + // since we truncate the test db, we need to add the postal_code_to_gbloc value + factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), "99744", "JEAT") + + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: postalCode, + UsPostRegionCityID: &zone2UUID, + }, + }, + }, nil) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &army, + }, + }, + }, nil) + + factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: destinationAddress, + LinkOnly: true, + }, + }, nil) + searchParams := services.MoveTaskOrderFetcherParams{ + IncludeHidden: false, + Locator: move.Locator, + ExcludeExternalShipments: true, + } + + actualMTO, err := mtoFetcher.FetchMoveTaskOrder(suite.AppContextForTest(), &searchParams) + suite.NoError(err) + suite.NotNil(actualMTO) + + if suite.Len(actualMTO.MTOShipments, 1) { + suite.Equal(move.ID.String(), actualMTO.ID.String()) + // the shipment should have a destination GBLOC value + suite.NotNil(actualMTO.MTOShipments[0].DestinationAddress.DestinationGbloc) + } + }) + suite.Run("Success with move that has only deleted shipments", func() { mtoWithAllShipmentsDeleted := factory.BuildMove(suite.DB(), nil, nil) factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ diff --git a/swagger-def/definitions/Address.yaml b/swagger-def/definitions/Address.yaml index baa869f59b3..0c018795ee2 100644 --- a/swagger-def/definitions/Address.yaml +++ b/swagger-def/definitions/Address.yaml @@ -161,6 +161,10 @@ properties: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: '^[A-Z]{4}$' + x-nullable: true required: - streetAddress1 - city diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index ab568b434c8..2456656b1c6 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -8301,6 +8301,10 @@ definitions: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: ^[A-Z]{4}$ + x-nullable: true required: - streetAddress1 - city diff --git a/swagger/internal.yaml b/swagger/internal.yaml index 84097cd100a..e6026ff442e 100644 --- a/swagger/internal.yaml +++ b/swagger/internal.yaml @@ -2758,6 +2758,10 @@ definitions: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: ^[A-Z]{4}$ + x-nullable: true required: - streetAddress1 - city diff --git a/swagger/pptas.yaml b/swagger/pptas.yaml index e2aa9b3c525..6b4223b52f7 100644 --- a/swagger/pptas.yaml +++ b/swagger/pptas.yaml @@ -245,6 +245,10 @@ definitions: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: ^[A-Z]{4}$ + x-nullable: true required: - streetAddress1 - city diff --git a/swagger/prime.yaml b/swagger/prime.yaml index 83ef52b06c7..c42c5608559 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -2955,6 +2955,10 @@ definitions: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: ^[A-Z]{4}$ + x-nullable: true required: - streetAddress1 - city diff --git a/swagger/prime_v2.yaml b/swagger/prime_v2.yaml index 00c4e8d169b..815a6e87ad5 100644 --- a/swagger/prime_v2.yaml +++ b/swagger/prime_v2.yaml @@ -1566,6 +1566,10 @@ definitions: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: ^[A-Z]{4}$ + x-nullable: true required: - streetAddress1 - city diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index c478289f287..fcb9b1a0d40 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -1654,6 +1654,10 @@ definitions: type: string format: uuid example: c56a4180-65aa-42ec-a945-5fd21dec0538 + destinationGbloc: + type: string + pattern: ^[A-Z]{4}$ + x-nullable: true required: - streetAddress1 - city From 509f3fc29e37aecbe9fbed5372daee29c01406c9 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 22:55:00 +0000 Subject: [PATCH 49/52] comments --- .../20241220213134_add_destination_gbloc_db_function.up.sql | 4 ++-- pkg/models/address.go | 2 +- pkg/models/mto_shipments.go | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql b/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql index bd7d9b1db5d..4b679eb8d48 100644 --- a/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql +++ b/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql @@ -1,5 +1,5 @@ -- this function will handle getting the destination GBLOC associated with a shipment's destination address --- this only applies to OCONUS destination addresses on a shipment, but this also checks domestic shipments +-- this only applies to OCONUS destination addresses on a shipment, but this can also checks domestic shipments CREATE OR REPLACE FUNCTION get_destination_gbloc_for_shipment(shipment_id UUID) RETURNS TEXT AS $$ DECLARE @@ -9,7 +9,7 @@ DECLARE alaska_zone_ii BOOLEAN; market_code TEXT; BEGIN - -- get the shipment's market_code + -- get the shipment's market code to determine conditionals SELECT ms.market_code INTO market_code FROM mto_shipments ms diff --git a/pkg/models/address.go b/pkg/models/address.go index 6042ae53960..d89a163c9aa 100644 --- a/pkg/models/address.go +++ b/pkg/models/address.go @@ -34,7 +34,7 @@ type Address struct { IsOconus *bool `json:"is_oconus" db:"is_oconus"` UsPostRegionCityID *uuid.UUID `json:"us_post_region_cities_id" db:"us_post_region_cities_id"` UsPostRegionCity *UsPostRegionCity `belongs_to:"us_post_region_cities" fk_id:"us_post_region_cities_id"` - DestinationGbloc *string `db:"-"` + DestinationGbloc *string `db:"-"` // this tells Pop not to look in the db for this value } // TableName overrides the table name used by Pop. diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index 783188addaa..9c2506e3292 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -427,7 +427,6 @@ func GetDestinationGblocForShipment(db *pop.Connection, shipmentID uuid.UUID) (* return nil, fmt.Errorf("error fetching destination gbloc for shipment ID: %s with error %w", shipmentID, err) } - // return the ZIP code and port type, or nil if not found if gbloc != nil { return gbloc, nil } From f6408b9868670883466e64a1238b5973088a338e Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 23:05:01 +0000 Subject: [PATCH 50/52] added usmc test --- .../move_task_order_fetcher.go | 2 +- .../move_task_order_fetcher_test.go | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/pkg/services/move_task_order/move_task_order_fetcher.go b/pkg/services/move_task_order/move_task_order_fetcher.go index b41d6bc9176..1d30aef5ceb 100644 --- a/pkg/services/move_task_order/move_task_order_fetcher.go +++ b/pkg/services/move_task_order/move_task_order_fetcher.go @@ -282,7 +282,7 @@ func (f moveTaskOrderFetcher) FetchMoveTaskOrder(appCtx appcontext.AppContext, s // USMC always goes to the USMC GBLOC if mto.MTOShipments[i].DestinationAddress != nil { if *mto.Orders.ServiceMember.Affiliation == models.AffiliationMARINES { - *mto.MTOShipments[i].DestinationAddress.DestinationGbloc = "USMC" + mto.MTOShipments[i].DestinationAddress.DestinationGbloc = models.StringPointer("USMC") } else { mto.MTOShipments[i].DestinationAddress.DestinationGbloc, err = models.GetDestinationGblocForShipment(appCtx.DB(), mto.MTOShipments[i].ID) if err != nil { diff --git a/pkg/services/move_task_order/move_task_order_fetcher_test.go b/pkg/services/move_task_order/move_task_order_fetcher_test.go index fb59f8209f3..a80be4aa524 100644 --- a/pkg/services/move_task_order/move_task_order_fetcher_test.go +++ b/pkg/services/move_task_order/move_task_order_fetcher_test.go @@ -401,6 +401,45 @@ func (suite *MoveTaskOrderServiceSuite) TestMoveTaskOrderFetcher() { } }) + suite.Run("Success with Prime available move, returns USMC destination GBLOC for USMC move", func() { + usmc := models.AffiliationMARINES + + destinationAddress := factory.BuildAddress(suite.DB(), nil, nil) + move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &usmc, + }, + }, + }, nil) + + factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: destinationAddress, + LinkOnly: true, + }, + }, nil) + searchParams := services.MoveTaskOrderFetcherParams{ + IncludeHidden: false, + Locator: move.Locator, + ExcludeExternalShipments: true, + } + + actualMTO, err := mtoFetcher.FetchMoveTaskOrder(suite.AppContextForTest(), &searchParams) + suite.NoError(err) + suite.NotNil(actualMTO) + + if suite.Len(actualMTO.MTOShipments, 1) { + suite.Equal(move.ID.String(), actualMTO.ID.String()) + suite.NotNil(actualMTO.MTOShipments[0].DestinationAddress.DestinationGbloc) + suite.Equal(*actualMTO.MTOShipments[0].DestinationAddress.DestinationGbloc, "USMC") + } + }) + suite.Run("Success with move that has only deleted shipments", func() { mtoWithAllShipmentsDeleted := factory.BuildMove(suite.DB(), nil, nil) factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ From 55c862950a184157476aa5296504e16d80afa02c Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 26 Dec 2024 13:47:23 +0000 Subject: [PATCH 51/52] updated db func to include USMC check, added test --- ...4_add_destination_gbloc_db_function.up.sql | 5 ++ pkg/models/mto_shipments_test.go | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql b/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql index 4b679eb8d48..0375f64d044 100644 --- a/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql +++ b/migrations/app/schema/20241220213134_add_destination_gbloc_db_function.up.sql @@ -45,6 +45,11 @@ BEGIN JOIN mto_shipments ms ON ms.move_id = m.id WHERE ms.id = shipment_id; + -- if the service member is USMC, return 'USMC' + IF service_member_affiliation = 'MARINES' THEN + RETURN 'USMC'; + END IF; + SELECT upc.uspr_zip_id INTO zip FROM addresses a diff --git a/pkg/models/mto_shipments_test.go b/pkg/models/mto_shipments_test.go index 1b92fbb7035..4014aa90d12 100644 --- a/pkg/models/mto_shipments_test.go +++ b/pkg/models/mto_shipments_test.go @@ -435,4 +435,53 @@ func (suite *ModelSuite) TestGetDestinationGblocForShipment() { suite.NotNil(gbloc) suite.Equal(*gbloc, "JEAT") }) + suite.Run("success - get GBLOC for USMC in AK Zone II", func() { + // Create a USMC move in Alaska Zone II + // this should always return USMC + zone2UUID, err := uuid.FromString("66768964-e0de-41f3-b9be-7ef32e4ae2b4") + suite.FatalNoError(err) + usmc := models.AffiliationMARINES + postalCode := "99501" + // since we truncate the test db, we need to add the postal_code_to_gbloc value + // this doesn't matter to the db function because it will check for USMC but we are just verifying it won't be JEAT despite the zip matching + factory.FetchOrBuildPostalCodeToGBLOC(suite.DB(), "99744", "JEAT") + + destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: postalCode, + UsPostRegionCityID: &zone2UUID, + }, + }, + }, nil) + + move := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ + { + Model: models.ServiceMember{ + Affiliation: &usmc, + }, + }, + }, nil) + + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: destinationAddress, + LinkOnly: true, + }, + }, nil) + + gbloc, err := models.GetDestinationGblocForShipment(suite.DB(), shipment.ID) + suite.NoError(err) + suite.NotNil(gbloc) + suite.Equal(*gbloc, "USMC") + }) } From 1ac32cdfad43652c60b0da90184b1d256a137ebf Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 20 Dec 2024 23:10:03 +0000 Subject: [PATCH 52/52] if it broke, ya gotta fix