Skip to content

Commit

Permalink
Merge pull request #14514 from transcom/MAIN-B-22146-defect-incorrect…
Browse files Browse the repository at this point in the history
…-mileage-destination-SIT

MAIN - B-22146 - Defect - Incorrect mileage destination SIT
  • Loading branch information
WeatherfordAaron authored Jan 9, 2025
2 parents 34fa5ca + 1778db7 commit d45a6a6
Show file tree
Hide file tree
Showing 4 changed files with 367 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service
planner := keyData.planner
db := appCtx.DB()
var distanceMiles int
var totalDistanceMiles int
hasApprovedDestinationSIT := false

// Make sure there's an MTOShipment since that's nullable
mtoShipmentID := keyData.mtoShipmentID
Expand All @@ -41,7 +43,12 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service
}
}

err = appCtx.DB().EagerPreload("DeliveryAddressUpdate", "DeliveryAddressUpdate.OriginalAddress", "DeliveryAddressUpdate.NewAddress", "MTOServiceItems", "Distance").Find(&mtoShipment, mtoShipment.ID)
err = appCtx.DB().EagerPreload(
"MTOServiceItems",
"Distance",
"PickupAddress",
"DestinationAddress",
).Find(&mtoShipment, mtoShipment.ID)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -77,58 +84,52 @@ func (r DistanceZipLookup) lookup(appCtx appcontext.AppContext, keyData *Service
return "", apperror.NewInvalidInputError(*mtoShipmentID, fmt.Errorf("%s", errorMsgForDestinationZip), nil, errorMsgForDestinationZip)
}

serviceCode := keyData.MTOServiceItem.ReService.Code
switch serviceCode {
case models.ReServiceCodeDLH, models.ReServiceCodeDSH, models.ReServiceCodeFSC:
for _, si := range mtoShipment.MTOServiceItems {
siCopy := si
err := appCtx.DB().EagerPreload("ReService", "ApprovedAt").Find(&siCopy, siCopy.ID)
if err != nil {
return "", err
}

switch siCopy.ReService.Code {
case models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDFSIT, models.ReServiceCodeDDSFSC:
if mtoShipment.DeliveryAddressUpdate != nil && mtoShipment.DeliveryAddressUpdate.Status == models.ShipmentAddressUpdateStatusApproved {
if siCopy.ApprovedAt != nil {
if mtoShipment.DeliveryAddressUpdate.UpdatedAt.After(*siCopy.ApprovedAt) {
destinationZip = mtoShipment.DeliveryAddressUpdate.OriginalAddress.PostalCode
} else {
destinationZip = mtoShipment.DeliveryAddressUpdate.NewAddress.PostalCode
}
}
}
}
for _, si := range mtoShipment.MTOServiceItems {
siCopy := si
err := appCtx.DB().EagerPreload("ReService").Find(&siCopy, siCopy.ID)
if err != nil {
return "", err
}

if mtoShipment.DeliveryAddressUpdate != nil && mtoShipment.DeliveryAddressUpdate.Status == models.ShipmentAddressUpdateStatusApproved {
distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, mtoShipment.DeliveryAddressUpdate.NewAddress.PostalCode, false, false)
if err != nil {
return "", err
switch siCopy.ReService.Code {
case models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDFSIT, models.ReServiceCodeDDSFSC:
if siCopy.Status == models.MTOServiceItemStatusApproved {
hasApprovedDestinationSIT = true
}
return strconv.Itoa(distanceMiles), nil
}
}

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
totalDistanceMiles = distanceMiles
} else if hasApprovedDestinationSIT {
// from pickup zip to delivery zip
totalDistanceMiles, err = planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, mtoShipment.DestinationAddress.PostalCode, false, internationalShipment)
if err != nil {
return "", err
}
// from pickup zip to Destination SIT zip
distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false, internationalShipment)
if err != nil {
return "", err
}
} else {
distanceMiles, err = planner.ZipTransitDistance(appCtx, pickupZip, destinationZip, false, internationalShipment)
if err != nil {
return "", err
}
totalDistanceMiles = distanceMiles
}

miles := unit.Miles(distanceMiles)
mtoShipment.Distance = &miles
err = db.Save(&mtoShipment)
if err != nil {
return "", err
miles := unit.Miles(totalDistanceMiles)
if mtoShipment.Distance == nil || mtoShipment.Distance.Int() != totalDistanceMiles {
mtoShipment.Distance = &miles
err = db.Save(&mtoShipment)
if err != nil {
return "", err
}
}

return strconv.Itoa(distanceMiles), nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,88 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() {
suite.Equal(unit.Miles(defaultInternationalZipDistance), *mtoShipment.Distance)
})

suite.Run("Calculate transit zip distance with an approved Destination SIT 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),
},
})
now := time.Now()

destinationAddress := factory.BuildAddress(suite.DB(), []factory.Customization{
{
Model: models.Address{
PostalCode: "88101",
},
},
}, nil)

mtoServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{
{
Model: models.Address{
PostalCode: "33607",
},
Type: &factory.Addresses.PickupAddress,
},
{
Model: models.Address{
PostalCode: "90210",
},
Type: &factory.Addresses.DeliveryAddress,
},
}, []factory.Trait{
factory.GetTraitAvailableToPrimeMove,
})

factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{
{
Model: models.ReService{
Code: models.ReServiceCodeDDFSIT,
Name: models.ReServiceCodeDDFSIT.String(),
},
},
{
Model: models.MTOServiceItem{
Status: models.MTOServiceItemStatusApproved,
ApprovedAt: &now,
},
},
{
Model: destinationAddress,
LinkOnly: true,
Type: &factory.Addresses.SITDestinationOriginalAddress,
},
{
Model: mtoServiceItem.MTOShipment,
LinkOnly: true,
},
}, []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(defaultZipDistance)
suite.Equal(expected, distanceStr)

var mtoShipment models.MTOShipment
err = suite.DB().Find(&mtoShipment, mtoServiceItem.MTOShipmentID)
suite.NoError(err)

suite.Equal(unit.Miles(defaultZipDistance), *mtoShipment.Distance)
})

suite.Run("Calculate zip distance lookup without a saved service item", func() {
ppmShipment := factory.BuildPPMShipment(suite.DB(), nil, nil)

Expand All @@ -150,7 +232,7 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() {
suite.Equal(unit.Miles(defaultZipDistance), *ppmShipment.Shipment.Distance)
})

suite.Run("Call ZipTransitDistance on non-PPMs with shipments that have a distance", func() {
suite.Run("Call ZipTransitDistance on PPMs with shipments that have a distance", func() {
miles := unit.Miles(defaultZipDistance)
ppmShipment := factory.BuildPPMShipment(suite.DB(), []factory.Customization{
{
Expand Down Expand Up @@ -181,39 +263,6 @@ func (suite *ServiceParamValueLookupsSuite) TestDistanceLookup() {
suite.Equal(fmt.Sprintf("%d", defaultZipDistance), distance)
})

suite.Run("Do not call ZipTransitDistance on PPMs with shipments that have a distance", func() {
miles := unit.Miles(defaultZipDistance)
shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{
{
Model: models.MTOShipment{
Distance: &miles,
ShipmentType: models.MTOShipmentTypeHHG,
},
},
}, nil)

distanceZipLookup := DistanceZipLookup{
PickupAddress: models.Address{PostalCode: shipment.PickupAddress.PostalCode},
DestinationAddress: models.Address{PostalCode: shipment.DestinationAddress.PostalCode},
}

appContext := suite.AppContextForTest()
distance, err := distanceZipLookup.lookup(appContext, &ServiceItemParamKeyData{
planner: suite.planner,
mtoShipmentID: &shipment.ID,
})
suite.NoError(err)

planner := suite.planner.(*mocks.Planner)
planner.AssertNotCalled(suite.T(), "ZipTransitDistance", appContext, shipment.PickupAddress.PostalCode, shipment.DestinationAddress.PostalCode, false, false)

err = suite.DB().Reload(&shipment)
suite.NoError(err)

suite.Equal(unit.Miles(defaultZipDistance), *shipment.Distance)
suite.Equal(fmt.Sprintf("%d", defaultZipDistance), distance)
})

suite.Run("Sucessfully updates mtoShipment distance when the pickup and destination zips are the same", func() {
testdatagen.MakeReContractYear(suite.DB(), testdatagen.Assertions{
ReContractYear: models.ReContractYear{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,8 @@ func InitializeLookups(appCtx appcontext.AppContext, shipment models.MTOShipment
MTOShipment: shipment,
}

serviceDestinationAddress, err := GetDestinationForDistanceLookup(appCtx, shipment, &serviceItem)
if err != nil {
return nil
}
serviceDestinationAddress := GetDestinationAfterCheckingSIT(appCtx, shipment, &serviceItem)

lookups[models.ServiceItemParamNameDistanceZip] = DistanceZipLookup{
PickupAddress: *shipment.PickupAddress,
DestinationAddress: serviceDestinationAddress,
Expand Down Expand Up @@ -322,7 +320,7 @@ func InitializeLookups(appCtx appcontext.AppContext, shipment models.MTOShipment
}

lookups[models.ServiceItemParamNameZipDestAddress] = ZipAddressLookup{
Address: *shipment.DestinationAddress,
Address: serviceDestinationAddress,
}

lookups[models.ServiceItemParamNameMTOAvailableToPrimeAt] = MTOAvailableToPrimeAtLookup{}
Expand Down Expand Up @@ -446,43 +444,39 @@ func InitializeLookups(appCtx appcontext.AppContext, shipment models.MTOShipment
return lookups
}

func GetDestinationForDistanceLookup(appCtx appcontext.AppContext, mtoShipment models.MTOShipment, mtoServiceItem *models.MTOServiceItem) (models.Address, error) {
// check additional conditions to determine the correct destination address to use for HHG shipment DLH, DSH, & FSC.
// we use DeliveryAddressUpdate.SIToriginalAddress if the shipment destination address update was made after Destination SIT was approved.
// if the shipment does not have a Destination SIT and a destination shipment update was made, then we use the new address.
func GetDestinationAfterCheckingSIT(appCtx appcontext.AppContext, mtoShipment models.MTOShipment, mtoServiceItem *models.MTOServiceItem) models.Address {
if mtoServiceItem == nil || mtoShipment.ShipmentType != models.MTOShipmentTypeHHG || (mtoServiceItem.ReService.Code != models.ReServiceCodeDLH && mtoServiceItem.ReService.Code != models.ReServiceCodeDSH && mtoServiceItem.ReService.Code != models.ReServiceCodeFSC) {
return *mtoShipment.DestinationAddress, nil
return *mtoShipment.DestinationAddress
}
shipmentCopy := mtoShipment
err := appCtx.DB().Eager("DeliveryAddressUpdate.Status", "DeliveryAddressUpdate.UpdatedAt", "DeliveryAddressUpdate.OriginalAddress", "DeliveryAddressUpdate.NewAddress", "MTOServiceItems", "DestinationAddress").Find(&shipmentCopy, mtoShipment.ID)
err := appCtx.DB().Eager("MTOServiceItems").Find(&shipmentCopy, mtoShipment.ID)
if err != nil {
return models.Address{}, apperror.NewNotFoundError(shipmentCopy.ID, "MTOShipment not found in Destination For Distance Lookup")
return *mtoShipment.DestinationAddress
}
if len(shipmentCopy.MTOServiceItems) == 0 {
return *mtoShipment.DestinationAddress, nil
return *mtoShipment.DestinationAddress
}

var result models.Address
// return SITDestinationOriginalAddress if an approved Destination SIT exists
for _, si := range shipmentCopy.MTOServiceItems {
siCopy := si
err := appCtx.DB().Eager("ReService").Find(&siCopy, siCopy.ID)
err := appCtx.DB().Eager("ReService", "SITDestinationOriginalAddress").Find(&siCopy, siCopy.ID)
if err != nil {
return models.Address{}, apperror.NewNotFoundError(siCopy.ID, "MTOServiceItem not found in Destination For Distance Lookup")
return *mtoShipment.DestinationAddress
}

switch siCopy.ReService.Code {
case models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDFSIT, models.ReServiceCodeDDSFSC:
if shipmentCopy.DeliveryAddressUpdate != nil && shipmentCopy.DeliveryAddressUpdate.Status == models.ShipmentAddressUpdateStatusApproved {
if siCopy.ApprovedAt != nil && shipmentCopy.DeliveryAddressUpdate.UpdatedAt.After(*siCopy.ApprovedAt) {
return shipmentCopy.DeliveryAddressUpdate.OriginalAddress, nil
}
return shipmentCopy.DeliveryAddressUpdate.NewAddress, nil
if siCopy.Status == models.MTOServiceItemStatusApproved && siCopy.SITDestinationOriginalAddress != nil {
return *siCopy.SITDestinationOriginalAddress
}
}
}
if shipmentCopy.DeliveryAddressUpdate.Status == models.ShipmentAddressUpdateStatusApproved {
result = shipmentCopy.DeliveryAddressUpdate.NewAddress
} else {
result = *shipmentCopy.DestinationAddress
}
return result, nil

return *mtoShipment.DestinationAddress
}

// serviceItemNeedsParamKey wrapper for using paramCache.ServiceItemNeedsParamKey, if s.paramCache is nil
Expand Down
Loading

0 comments on commit d45a6a6

Please sign in to comment.