diff --git a/pkg/route/hhg_planner.go b/pkg/route/hhg_planner.go index f69cc2c0591..7b9f5af4039 100644 --- a/pkg/route/hhg_planner.go +++ b/pkg/route/hhg_planner.go @@ -58,7 +58,8 @@ func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source str sourceZip3 := sourceZip5[0:3] destZip3 := destZip5[0:3] - if sourceZip3 == destZip3 || isInternationalShipment { + // if the first 3 numbers of the ZIPs are the same then we need to get the exact distance between the full ZIP5s + if sourceZip3 == destZip3 { if sourceZip5 == destZip5 { return 1, nil } @@ -66,19 +67,21 @@ func (p *hhgPlanner) ZipTransitDistance(appCtx appcontext.AppContext, source str } else { // 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 - // this only applies to domestic shipments - 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 since international addresses do not have base point cities + 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) + } } } diff --git a/pkg/route/hhg_planner_test.go b/pkg/route/hhg_planner_test.go index a2725ef1c3a..099500fd85b 100644 --- a/pkg/route/hhg_planner_test.go +++ b/pkg/route/hhg_planner_test.go @@ -125,4 +125,23 @@ func (suite *GHCTestSuite) TestHHGZipTransitDistance() { suite.Error(err) suite.Equal(0, distance) }) + + suite.Run("ZipTransitDistance returns Rand McNally distance when isInternationalShipment is true", func() { + testSoapClient := &ghcmocks.SoapCaller{} + + plannerMileage := NewDTODZip5Distance(fakeUsername, fakePassword, testSoapClient, false) + planner := NewHHGPlanner(plannerMileage) + fromZip := "74133" + toZip := "99702" + + // get the result from the test db + var zip3Distance models.Zip3Distance + err := suite.DB().Where("from_zip3 = $1 AND to_zip3 = $2", fromZip[0:3], toZip[0:3]).First(&zip3Distance) + suite.NoError(err) + + // confirm we get the same + distance, err := planner.ZipTransitDistance(suite.AppContextForTest(), "74133", "99702", true) + suite.NoError(err) + suite.Equal(zip3Distance.DistanceMiles, distance) + }) } 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 0a81d7ede20..75265f566d3 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -365,6 +365,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, if err != nil { return nil, err } + isInternationalShipment := mtoShipment.MarketCode == models.MarketCodeInternational // Check to see if there is already a SIT Destination Original Address // by checking for the ID before trying to set one on the service item. @@ -411,7 +412,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, serviceItem.ReService.Code == models.ReServiceCodeIDDSIT || serviceItem.ReService.Code == models.ReServiceCodeIDSFSC { // 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, isInternationalShipment) if err != nil { return nil, err } @@ -425,7 +426,7 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, serviceItem.ReService.Code == models.ReServiceCodeIOPSIT || serviceItem.ReService.Code == models.ReServiceCodeIOSFSC { // 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, isInternationalShipment) if err != nil { return nil, err } @@ -568,7 +569,8 @@ 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) + isInternationalShipment := shipment.MarketCode == models.MarketCodeInternational + distance, err := planner.ZipTransitDistance(appCtx, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, isInternationalShipment) if err != nil { return nil, apperror.NewUnprocessableEntityError("cannot calculate distance between pickup and destination addresses") @@ -800,6 +802,7 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItem( // this only applies to international shipments if oldServiceItem.POELocationID != mtoServiceItem.POELocationID || oldServiceItem.PODLocationID != mtoServiceItem.PODLocationID { shipment := oldServiceItem.MTOShipment + isInternationalShipment := shipment.MarketCode == models.MarketCodeInternational if shipment.PickupAddress != nil && shipment.DestinationAddress != nil && (mtoServiceItem.POELocation != nil && mtoServiceItem.POELocation.UsPostRegionCity.UsprZipID != "" || mtoServiceItem.PODLocation != nil && mtoServiceItem.PODLocation.UsPostRegionCity.UsprZipID != "") { @@ -814,8 +817,9 @@ func (p *mtoServiceItemUpdater) UpdateMTOServiceItem( 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) + // we need to get the mileage first, the db proc will consume that + // only international shipments will have POE/PODFSC service items + mileage, err := p.planner.ZipTransitDistance(appCtx, pickupZip, destZip, isInternationalShipment) if err != nil { return err } diff --git a/pkg/services/mto_shipment/shipment_approver.go b/pkg/services/mto_shipment/shipment_approver.go index 801507ea7a6..c4c14f75879 100644 --- a/pkg/services/mto_shipment/shipment_approver.go +++ b/pkg/services/mto_shipment/shipment_approver.go @@ -111,7 +111,8 @@ func (f *shipmentApprover) ApproveShipment(appCtx appcontext.AppContext, shipmen pickupZip = *portZip destZip = shipment.DestinationAddress.PostalCode } - // we need to get the mileage from DTOD first, the db proc will consume that + // we need to get the mileage first, the db proc will consume that + // only international shipments will have port data, so setting isInternationalShipment to true here mileage, err := f.planner.ZipTransitDistance(appCtx, pickupZip, destZip, true) if err != nil { return err 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 3acd31b33fb..697f79ef755 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -122,6 +122,7 @@ func (f *shipmentAddressUpdateRequester) doesDeliveryAddressUpdateChangeMileageB return false, nil } + // this only runs for domestic shipments so putting false for the isInternationalShipment value here previousDistance, err := f.planner.ZipTransitDistance(appCtx, originalPickupAddress.PostalCode, originalDeliveryAddress.PostalCode, false) if err != nil { return false, err @@ -354,14 +355,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, isInternationalShipment) } 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, isInternationalShipment) if err != nil { return nil, err } @@ -698,8 +699,8 @@ func (f *shipmentAddressUpdateRequester) ReviewShipmentAddressChange(appCtx appc 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) + // we need to get the mileage first, the db proc will consume that + mileage, err := f.planner.ZipTransitDistance(appCtx, pickupZip, destZip, isInternationalShipment) if err != nil { return err }