From ec1649c7539507b3cc4d7fc7ad3894a1980f30b1 Mon Sep 17 00:00:00 2001 From: pambecker Date: Fri, 17 Jan 2025 02:12:46 +0000 Subject: [PATCH] revert previous idea --- ...date_postal_codes_and_gblocs_for_ak.up.sql | 33 +++----- pkg/handlers/ghcapi/orders.go | 46 +++++++---- pkg/handlers/internalapi/orders.go | 78 ++++++++++++++----- pkg/models/address.go | 7 +- pkg/models/address_test.go | 16 ++-- pkg/models/move.go | 30 ++++--- pkg/services/order/order_updater.go | 51 ++++++++---- 7 files changed, 169 insertions(+), 92 deletions(-) diff --git a/migrations/app/schema/20250103142533_update_postal_codes_and_gblocs_for_ak.up.sql b/migrations/app/schema/20250103142533_update_postal_codes_and_gblocs_for_ak.up.sql index fe88f410e2f..97229ad0bc6 100644 --- a/migrations/app/schema/20250103142533_update_postal_codes_and_gblocs_for_ak.up.sql +++ b/migrations/app/schema/20250103142533_update_postal_codes_and_gblocs_for_ak.up.sql @@ -44,9 +44,9 @@ SELECT move_id, gbloc FROM ( DROP FUNCTION IF EXISTS get_address_gbloc; + CREATE OR REPLACE FUNCTION public.get_address_gbloc( address_id UUID, - postal_code TEXT, affiliation TEXT, OUT gbloc TEXT ) @@ -56,13 +56,8 @@ DECLARE v_count INT; v_bos_count INT; v_dept_ind TEXT; - v_postal_code TEXT; -begin - IF address_id IS NOT NULL THEN - is_oconus := get_is_oconus(address_id); - ELSE - is_oconus := false; - END IF; +BEGIN + is_oconus := get_is_oconus(address_id); IF affiliation in ('AIR_FORCE','SPACE_FORCE') THEN v_dept_ind := 'AIR_AND_SPACE_FORCE'; @@ -146,28 +141,20 @@ begin ELSE --is conus - IF postal_code IS NULL THEN - - SELECT o.uspr_zip_id - INTO v_postal_code - FROM addresses a, v_locations o - WHERE a.us_post_region_cities_id = o.uprc_id - AND a.id = address_id; - - ELSE - v_postal_code := postal_code; - END IF; - SELECT j.gbloc INTO gbloc - FROM postal_code_to_gblocs j - WHERE j.postal_code = v_postal_code; + FROM addresses a, + v_locations o, + postal_code_to_gblocs j + WHERE a.us_post_region_cities_id = o.uprc_id + and o.uspr_zip_id = j.postal_code + and a.id = address_id; END IF; -- Raise an exception if no rate area is found IF gbloc IS NULL THEN - RAISE EXCEPTION 'GBLOC not found for address ID % for affiliation % postal_code % ', address_id, affiiation, postal_code; + RAISE EXCEPTION 'GBLOC not found for address ID % for affiliation %', address_id, affiiation; END IF; END; $$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/pkg/handlers/ghcapi/orders.go b/pkg/handlers/ghcapi/orders.go index c065f25712e..49ca15d9b9a 100644 --- a/pkg/handlers/ghcapi/orders.go +++ b/pkg/handlers/ghcapi/orders.go @@ -218,21 +218,41 @@ func (h CreateOrderHandler) Handle(params orderop.CreateOrderParams) middleware. return orderop.NewCreateOrderUnprocessableEntity(), err } - destinationGBLOC, err := models.FetchAddressPostalCodeGbloc(appCtx.DB(), newDutyLocation.Address, newDutyLocation.Address.PostalCode, serviceMember) - if err != nil { - err = apperror.NewBadDataError("New duty location GBLOC cannot be verified") - appCtx.Logger().Error(err.Error()) - return orderop.NewCreateOrderUnprocessableEntity(), err + var newDutyLocationGBLOC *string + if *newDutyLocation.Address.IsOconus { + newDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), newDutyLocation.Address, serviceMember) + if err != nil { + return nil, apperror.NewNotFoundError(newDutyLocation.ID, "while looking for Duty Location Oconus GBLOC") + } + newDutyLocationGBLOC = newDutyLocationGBLOCOconus + } else { + newDutyLocationGBLOCConus, err := models.FetchGBLOCForPostalCode(appCtx.DB(), newDutyLocation.Address.PostalCode) + if err != nil { + err = apperror.NewBadDataError("New duty location GBLOC cannot be verified") + appCtx.Logger().Error(err.Error()) + return orderop.NewCreateOrderUnprocessableEntity(), err + } + newDutyLocationGBLOC = &newDutyLocationGBLOCConus.GBLOC } - originDutyLocationGBLOC, err := models.FetchAddressPostalCodeGbloc(appCtx.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, serviceMember) - if err != nil { - switch err { - case sql.ErrNoRows: - return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location FetchAddressPostalCodeGbloc") - default: - return nil, apperror.NewQueryError("FetchAddressPostalCodeGbloc", err, "") + var originDutyLocationGBLOC *string + if *originDutyLocation.Address.IsOconus { + originDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), originDutyLocation.Address, serviceMember) + if err != nil { + return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location Oconus GBLOC") + } + originDutyLocationGBLOC = originDutyLocationGBLOCOconus + } else { + originDutyLocationGBLOCConus, err := models.FetchGBLOCForPostalCode(appCtx.DB(), originDutyLocation.Address.PostalCode) + if err != nil { + switch err { + case sql.ErrNoRows: + return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location PostalCodeToGBLOC") + default: + return nil, apperror.NewQueryError("PostalCodeToGBLOC", err, "") + } } + originDutyLocationGBLOC = &originDutyLocationGBLOCConus.GBLOC } grade := (internalmessages.OrderPayGrade)(*payload.Grade) @@ -313,7 +333,7 @@ func (h CreateOrderHandler) Handle(params orderop.CreateOrderParams) middleware. &entitlement, originDutyLocationGBLOC, packingAndShippingInstructions, - destinationGBLOC, + newDutyLocationGBLOC, ) if err != nil || verrs.HasAny() { return handlers.ResponseForVErrors(appCtx.Logger(), verrs, err), err diff --git a/pkg/handlers/internalapi/orders.go b/pkg/handlers/internalapi/orders.go index f589b32735d..2ee491048f8 100644 --- a/pkg/handlers/internalapi/orders.go +++ b/pkg/handlers/internalapi/orders.go @@ -167,9 +167,19 @@ func (h CreateOrdersHandler) Handle(params ordersop.CreateOrdersParams) middlewa return handlers.ResponseForError(appCtx.Logger(), err), err } - newDutyLocationGBLOC, err := models.FetchAddressPostalCodeGbloc(appCtx.DB(), newDutyLocation.Address, newDutyLocation.Address.PostalCode, serviceMember) - if err != nil { - return handlers.ResponseForError(appCtx.Logger(), err), err + var newDutyLocationGBLOC *string + if *newDutyLocation.Address.IsOconus { + newDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), newDutyLocation.Address, serviceMember) + if err != nil { + return nil, apperror.NewNotFoundError(newDutyLocation.ID, "while looking for Duty Location Oconus GBLOC") + } + newDutyLocationGBLOC = newDutyLocationGBLOCOconus + } else { + newDutyLocationGBLOCConus, err := models.FetchGBLOCForPostalCode(appCtx.DB(), newDutyLocation.Address.PostalCode) + if err != nil { + return handlers.ResponseForError(appCtx.Logger(), err), err + } + newDutyLocationGBLOC = &newDutyLocationGBLOCConus.GBLOC } var dependentsTwelveAndOver *int @@ -183,14 +193,24 @@ func (h CreateOrdersHandler) Handle(params ordersop.CreateOrdersParams) middlewa dependentsUnderTwelve = models.IntPointer(int(*payload.DependentsUnderTwelve)) } - originDutyLocationGBLOC, err := models.FetchAddressPostalCodeGbloc(appCtx.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, serviceMember) - if err != nil { - switch err { - case sql.ErrNoRows: - return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location FetchAddressPostalCodeGbloc") - default: - return nil, apperror.NewQueryError("FetchAddressPostalCodeGbloc", err, "") + var originDutyLocationGBLOC *string + if *originDutyLocation.Address.IsOconus { + originDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), originDutyLocation.Address, serviceMember) + if err != nil { + return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location Oconus GBLOC") } + originDutyLocationGBLOC = originDutyLocationGBLOCOconus + } else { + originDutyLocationGBLOCConus, err := models.FetchGBLOCForPostalCode(appCtx.DB(), originDutyLocation.Address.PostalCode) + if err != nil { + switch err { + case sql.ErrNoRows: + return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location PostalCodeToGBLOC") + default: + return nil, apperror.NewQueryError("PostalCodeToGBLOC", err, "") + } + } + originDutyLocationGBLOC = &originDutyLocationGBLOCConus.GBLOC } grade := payload.Grade @@ -363,11 +383,21 @@ func (h UpdateOrdersHandler) Handle(params ordersop.UpdateOrdersParams) middlewa return handlers.ResponseForError(appCtx.Logger(), err), err } - newDutyLocationGBLOC, err := models.FetchAddressPostalCodeGbloc(appCtx.DB(), dutyLocation.Address, dutyLocation.Address.PostalCode, order.ServiceMember) - if err != nil { - err = apperror.NewBadDataError("New duty location GBLOC cannot be verified") - appCtx.Logger().Error(err.Error()) - return handlers.ResponseForError(appCtx.Logger(), err), err + var newDutyLocationGBLOC *string + if *dutyLocation.Address.IsOconus { + newDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), dutyLocation.Address, order.ServiceMember) + if err != nil { + return nil, apperror.NewNotFoundError(dutyLocation.ID, "while looking for Duty Location Oconus GBLOC") + } + newDutyLocationGBLOC = newDutyLocationGBLOCOconus + } else { + newDutyLocationGBLOCConus, err := models.FetchGBLOCForPostalCode(appCtx.DB(), dutyLocation.Address.PostalCode) + if err != nil { + err = apperror.NewBadDataError("New duty location GBLOC cannot be verified") + appCtx.Logger().Error(err.Error()) + return handlers.ResponseForError(appCtx.Logger(), err), err + } + newDutyLocationGBLOC = &newDutyLocationGBLOCConus.GBLOC } if payload.OriginDutyLocationID != "" { @@ -382,11 +412,21 @@ func (h UpdateOrdersHandler) Handle(params ordersop.UpdateOrdersParams) middlewa order.OriginDutyLocation = &originDutyLocation order.OriginDutyLocationID = &originDutyLocationID - originGBLOC, originGBLOCerr := models.FetchAddressPostalCodeGbloc(appCtx.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, order.ServiceMember) - if originGBLOCerr != nil { - return handlers.ResponseForError(appCtx.Logger(), originGBLOCerr), originGBLOCerr + var originDutyLocationGBLOC *string + if *originDutyLocation.Address.IsOconus { + originDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), originDutyLocation.Address, order.ServiceMember) + if err != nil { + return handlers.ResponseForError(appCtx.Logger(), err), err + } + originDutyLocationGBLOC = originDutyLocationGBLOCOconus + } else { + originDutyLocationGBLOCConus, err := models.FetchGBLOCForPostalCode(appCtx.DB(), originDutyLocation.Address.PostalCode) + if err != nil { + return handlers.ResponseForError(appCtx.Logger(), err), err + } + originDutyLocationGBLOC = &originDutyLocationGBLOCConus.GBLOC } - order.OriginDutyLocationGBLOC = originGBLOC + order.OriginDutyLocationGBLOC = originDutyLocationGBLOC if payload.MoveID != "" { diff --git a/pkg/models/address.go b/pkg/models/address.go index a61cc9bf19b..29a6bedbcbb 100644 --- a/pkg/models/address.go +++ b/pkg/models/address.go @@ -212,12 +212,11 @@ func EvaluateIsOconus(address Address) bool { } } -// Fetches the GBLOC for a specific Address or Postal Code -// OCONUS will always use Address, while CONUS will use Postal Code -func FetchAddressPostalCodeGbloc(db *pop.Connection, address Address, postalCode string, serviceMember ServiceMember) (*string, error) { +// Fetches the GBLOC for a specific Address (for now this will be used for OCONUS) +func FetchAddressGbloc(db *pop.Connection, address Address, serviceMember ServiceMember) (*string, error) { var gbloc *string - err := db.RawQuery("SELECT * FROM get_address_gbloc($1, $2, $3)", address.ID, postalCode, serviceMember.Affiliation.String()). + err := db.RawQuery("SELECT * FROM get_address_gbloc($1, $2)", address.ID, serviceMember.Affiliation.String()). First(&gbloc) if err != nil { diff --git a/pkg/models/address_test.go b/pkg/models/address_test.go index b13a6cc4f55..63656953d3c 100644 --- a/pkg/models/address_test.go +++ b/pkg/models/address_test.go @@ -278,10 +278,10 @@ func (suite *ModelSuite) Test_FetchDutyLocationGblocForAK() { } suite.MustSave(&gblocAors) - gbloc, err := m.FetchAddressPostalCodeGbloc(suite.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, serviceMember) + gbloc, err := m.FetchAddressGbloc(suite.DB(), originDutyLocation.Address, serviceMember) suite.NoError(err) suite.NotNil(gbloc) - suite.Equal(gbloc, "MBFL") + suite.Equal(string(*gbloc), "MBFL") }) suite.Run("fetches duty location GBLOC for AK address, Zone II Army", func() { @@ -310,10 +310,10 @@ func (suite *ModelSuite) Test_FetchDutyLocationGblocForAK() { } suite.MustSave(&gblocAors) - gbloc, err := m.FetchAddressPostalCodeGbloc(suite.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, serviceMember) + gbloc, err := m.FetchAddressGbloc(suite.DB(), originDutyLocation.Address, serviceMember) suite.NoError(err) suite.NotNil(gbloc) - suite.Equal(gbloc, "JEAT") + suite.Equal(string(*gbloc), "JEAT") }) suite.Run("fetches duty location GBLOC for AK Cordova address, Zone IV", func() { @@ -342,10 +342,10 @@ func (suite *ModelSuite) Test_FetchDutyLocationGblocForAK() { } suite.MustSave(&gblocAors) - gbloc, err := m.FetchAddressPostalCodeGbloc(suite.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, serviceMember) + gbloc, err := m.FetchAddressGbloc(suite.DB(), originDutyLocation.Address, serviceMember) suite.NoError(err) suite.NotNil(gbloc) - suite.Equal(gbloc, "MAPS") + suite.Equal(string(*gbloc), "MAPS") }) suite.Run("fetches duty location GBLOC for AK NOT Cordova address, Zone IV", func() { @@ -374,9 +374,9 @@ func (suite *ModelSuite) Test_FetchDutyLocationGblocForAK() { } suite.MustSave(&gblocAors) - gbloc, err := m.FetchAddressPostalCodeGbloc(suite.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, serviceMember) + gbloc, err := m.FetchAddressGbloc(suite.DB(), originDutyLocation.Address, serviceMember) suite.NoError(err) suite.NotNil(gbloc) - suite.Equal(gbloc, "MAPK") + suite.Equal(string(*gbloc), "MAPK") }) } diff --git a/pkg/models/move.go b/pkg/models/move.go index 3b7fd610e69..e3b1b889bf8 100644 --- a/pkg/models/move.go +++ b/pkg/models/move.go @@ -215,19 +215,29 @@ func (m Move) GetDestinationGBLOC(db *pop.Connection) (string, error) { return "", err } - err = db.Load(&m.Orders, "ServiceMember") - if err != nil { - if err.Error() == RecordNotFoundErrorString { - return "", errors.WithMessage(err, "No Service Member found in the DB associated with moveID "+m.ID.String()) + var newGBLOC string + if *destinationAddress.IsOconus { + err := db.Load(&m.Orders, "ServiceMember") + if err != nil { + if err.Error() == RecordNotFoundErrorString { + return "", errors.WithMessage(err, "No Service Member found in the DB associated with moveID "+m.ID.String()) + } + return "", err } - return "", err - } - newGBLOC, err := FetchAddressPostalCodeGbloc(db, *destinationAddress, destinationAddress.PostalCode, m.Orders.ServiceMember) - if err != nil { - return "", err + newGBLOCOconus, err := FetchAddressGbloc(db, *destinationAddress, m.Orders.ServiceMember) + if err != nil { + return "", err + } + newGBLOC = *newGBLOCOconus + } else { + newGBLOCConus, err := FetchGBLOCForPostalCode(db, destinationAddress.PostalCode) + if err != nil { + return "", err + } + newGBLOC = newGBLOCConus.GBLOC } - return *newGBLOC, err + return newGBLOC, err } // GetDestinationAddress returns the address for the move. This ensures that business logic is centralized. diff --git a/pkg/services/order/order_updater.go b/pkg/services/order/order_updater.go index 93ade34887e..8fb4d7072e3 100644 --- a/pkg/services/order/order_updater.go +++ b/pkg/services/order/order_updater.go @@ -695,16 +695,27 @@ func updateOrderInTx(appCtx appcontext.AppContext, order models.Order, checks .. order.OriginDutyLocationID = &originDutyLocation.ID order.OriginDutyLocation = &originDutyLocation - dutyLocationGBLOC, err2 := models.FetchAddressPostalCodeGbloc(appCtx.DB(), originDutyLocation.Address, originDutyLocation.Address.PostalCode, order.ServiceMember) - if err2 != nil { - switch err2 { - case sql.ErrNoRows: - return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location PostalCodeToGBLOC") - default: - return nil, apperror.NewQueryError("PostalCodeToGBLOC", err, "") + var originDutyLocationGBLOC *string + if *originDutyLocation.Address.IsOconus { + originDutyLocationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), originDutyLocation.Address, order.ServiceMember) + if err != nil { + return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location Oconus GBLOC") } + originDutyLocationGBLOC = originDutyLocationGBLOCOconus + } else { + originDutyLocationGBLOCConus, err2 := models.FetchGBLOCForPostalCode(appCtx.DB(), originDutyLocation.Address.PostalCode) + if err2 != nil { + switch err2 { + case sql.ErrNoRows: + return nil, apperror.NewNotFoundError(originDutyLocation.ID, "while looking for Duty Location PostalCodeToGBLOC") + default: + return nil, apperror.NewQueryError("PostalCodeToGBLOC", err, "") + } + } + originDutyLocationGBLOC = &originDutyLocationGBLOCConus.GBLOC } - order.OriginDutyLocationGBLOC = dutyLocationGBLOC + + order.OriginDutyLocationGBLOC = originDutyLocationGBLOC } if order.Grade != nil || order.OriginDutyLocationID != nil { @@ -727,14 +738,24 @@ func updateOrderInTx(appCtx appcontext.AppContext, order models.Order, checks .. } } - newDestinationGBLOC, err := models.FetchAddressPostalCodeGbloc(appCtx.DB(), newDutyLocation.Address, newDutyLocation.Address.PostalCode, order.ServiceMember) - if err != nil { - switch err { - case sql.ErrNoRows: - return nil, apperror.NewNotFoundError(order.NewDutyLocationID, "while looking for DestinationGBLOC") - default: - return nil, apperror.NewQueryError("DestinationGBLOC", err, "") + var newDestinationGBLOC *string + if *newDutyLocation.Address.IsOconus { + newDestinationGBLOCOconus, err := models.FetchAddressGbloc(appCtx.DB(), newDutyLocation.Address, order.ServiceMember) + if err != nil { + return nil, apperror.NewNotFoundError(newDutyLocation.ID, "while looking for DestinationGBLOC Oconus") + } + newDestinationGBLOC = newDestinationGBLOCOconus + } else { + newDestinationGBLOCConus, err2 := models.FetchGBLOCForPostalCode(appCtx.DB(), newDutyLocation.Address.PostalCode) + if err2 != nil { + switch err { + case sql.ErrNoRows: + return nil, apperror.NewNotFoundError(order.NewDutyLocationID, "while looking for DestinationGBLOC") + default: + return nil, apperror.NewQueryError("DestinationGBLOC", err, "") + } } + newDestinationGBLOC = &newDestinationGBLOCConus.GBLOC } order.NewDutyLocationID = newDutyLocation.ID