Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

B-21581 #14521

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

B-21581 #14521

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/transcom/mymove/pkg/factory"
"github.com/transcom/mymove/pkg/gen/ghcmessages"
"github.com/transcom/mymove/pkg/gen/internalmessages"
"github.com/transcom/mymove/pkg/handlers"
"github.com/transcom/mymove/pkg/models"
"github.com/transcom/mymove/pkg/models/roles"
Expand Down Expand Up @@ -315,6 +316,93 @@ func (suite *PayloadsSuite) TestShipmentAddressUpdate() {
})
}

func (suite *PayloadsSuite) TestMoveWithGBLOC() {
defaultOrdersNumber := "ORDER3"
defaultTACNumber := "F8E1"
defaultDepartmentIndicator := "AIR_AND_SPACE_FORCE"
defaultGrade := "E_1"
defaultHasDependents := false
defaultSpouseHasProGear := false
defaultOrdersType := internalmessages.OrdersTypePERMANENTCHANGEOFSTATION
defaultOrdersTypeDetail := internalmessages.OrdersTypeDetail("HHG_PERMITTED")
defaultStatus := models.OrderStatusDRAFT
testYear := 2018
defaultIssueDate := time.Date(testYear, time.March, 15, 0, 0, 0, 0, time.UTC)
defaultReportByDate := time.Date(testYear, time.August, 1, 0, 0, 0, 0, time.UTC)
defaultGBLOC := "KKFA"

originDutyLocation := models.DutyLocation{
Name: "Custom Origin",
}
originDutyLocationTOName := "origin duty location transportation office"
firstName := "customFirst"
lastName := "customLast"
serviceMember := models.ServiceMember{
FirstName: &firstName,
LastName: &lastName,
}
uploadedOrders := models.Document{
ID: uuid.Must(uuid.NewV4()),
}
dependents := 7
entitlement := models.Entitlement{
TotalDependents: &dependents,
}
amendedOrders := models.Document{
ID: uuid.Must(uuid.NewV4()),
}
// Create order
order := factory.BuildOrder(suite.DB(), []factory.Customization{
{
Model: originDutyLocation,
Type: &factory.DutyLocations.OriginDutyLocation,
},
{
Model: models.TransportationOffice{
Name: originDutyLocationTOName,
},
Type: &factory.TransportationOffices.OriginDutyLocation,
},
{
Model: serviceMember,
},
{
Model: uploadedOrders,
Type: &factory.Documents.UploadedOrders,
},
{
Model: entitlement,
},
{
Model: amendedOrders,
Type: &factory.Documents.UploadedAmendedOrders,
},
}, nil)

suite.Equal(defaultOrdersNumber, *order.OrdersNumber)
suite.Equal(defaultTACNumber, *order.TAC)
suite.Equal(defaultDepartmentIndicator, *order.DepartmentIndicator)
suite.Equal(defaultGrade, string(*order.Grade))
suite.Equal(defaultHasDependents, order.HasDependents)
suite.Equal(defaultSpouseHasProGear, order.SpouseHasProGear)
suite.Equal(defaultOrdersType, order.OrdersType)
suite.Equal(defaultOrdersTypeDetail, *order.OrdersTypeDetail)
suite.Equal(defaultStatus, order.Status)
suite.Equal(defaultIssueDate, order.IssueDate)
suite.Equal(defaultReportByDate, order.ReportByDate)
suite.Equal(defaultGBLOC, *order.OriginDutyLocationGBLOC)

suite.Equal(originDutyLocation.Name, order.OriginDutyLocation.Name)
suite.Equal(originDutyLocationTOName, order.OriginDutyLocation.TransportationOffice.Name)
suite.Equal(*serviceMember.FirstName, *order.ServiceMember.FirstName)
suite.Equal(*serviceMember.LastName, *order.ServiceMember.LastName)
suite.Equal(uploadedOrders.ID, order.UploadedOrdersID)
suite.Equal(uploadedOrders.ID, order.UploadedOrders.ID)
suite.Equal(*entitlement.TotalDependents, *order.Entitlement.TotalDependents)
suite.Equal(amendedOrders.ID, *order.UploadedAmendedOrdersID)
suite.Equal(amendedOrders.ID, order.UploadedAmendedOrders.ID)
}

func (suite *PayloadsSuite) TestWeightTicketUpload() {
uploadID, _ := uuid.NewV4()
testURL := "https://testurl.com"
Expand Down
6 changes: 6 additions & 0 deletions pkg/handlers/internalapi/orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,12 @@ func (h UpdateOrdersHandler) Handle(params ordersop.UpdateOrdersParams) middlewa
order.OriginDutyLocation = &originDutyLocation
order.OriginDutyLocationID = &originDutyLocationID

originGBLOC, originGBLOCerr := models.FetchGBLOCForPostalCode(appCtx.DB(), originDutyLocation.Address.PostalCode)
if originGBLOCerr != nil {
return handlers.ResponseForError(appCtx.Logger(), originGBLOCerr), originGBLOCerr
}
order.OriginDutyLocationGBLOC = &originGBLOC.GBLOC

if payload.MoveID != "" {

moveID, err := uuid.FromString(payload.MoveID.String())
Expand Down
124 changes: 124 additions & 0 deletions pkg/handlers/internalapi/orders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,130 @@ func (suite *HandlerSuite) TestUpdateOrdersHandler() {
})
}

func (suite *HandlerSuite) TestUpdateOrdersHandlerOriginPostalCodeAndGBLOC() {
factory.BuildPostalCodeToGBLOC(suite.DB(), []factory.Customization{
{
Model: models.PostalCodeToGBLOC{
PostalCode: "90210",
GBLOC: "KKFA",
},
},
}, nil)
factory.BuildPostalCodeToGBLOC(suite.DB(), []factory.Customization{
{
Model: models.PostalCodeToGBLOC{
PostalCode: "35023",
GBLOC: "CNNQ",
},
},
}, nil)

firstAddress := factory.BuildAddress(suite.DB(), []factory.Customization{
{
Model: models.Address{
PostalCode: "90210",
},
},
}, nil)
updatedAddress := factory.BuildAddress(suite.DB(), []factory.Customization{
{
Model: models.Address{
PostalCode: "35023",
},
},
}, nil)
dutyLocation := factory.BuildDutyLocation(suite.DB(), []factory.Customization{
{
Model: models.DutyLocation{
AddressID: firstAddress.ID,
},
},
}, nil)
updatedDutyLocation := factory.BuildDutyLocation(suite.DB(), []factory.Customization{
{
Model: models.DutyLocation{
AddressID: updatedAddress.ID,
},
},
}, nil)
newDutyLocation := factory.BuildDutyLocation(suite.DB(), nil, nil)

order := factory.BuildOrder(suite.DB(), []factory.Customization{
{
Model: models.Order{
OriginDutyLocationID: &dutyLocation.ID,
NewDutyLocationID: newDutyLocation.ID,
},
},
}, nil)

fetchedOrder, err := models.FetchOrder(suite.DB(), order.ID)
suite.NoError(err)

var fetchedPostalCode, fetchedGBLOC string
fetchedPostalCode, err = fetchedOrder.GetOriginPostalCode(suite.DB())
suite.NoError(err)
fetchedGBLOC, err = fetchedOrder.GetOriginGBLOC(suite.DB())
suite.NoError(err)

suite.Equal("90210", fetchedPostalCode)
suite.Equal("KKFA", fetchedGBLOC)

newOrdersType := internalmessages.OrdersTypePERMANENTCHANGEOFSTATION
issueDate := time.Date(2018, time.March, 10, 0, 0, 0, 0, time.UTC)
reportByDate := time.Date(2018, time.August, 1, 0, 0, 0, 0, time.UTC)
deptIndicator := internalmessages.DeptIndicatorAIRANDSPACEFORCE

payload := &internalmessages.CreateUpdateOrders{
OrdersType: &order.OrdersType,
NewDutyLocationID: handlers.FmtUUID(order.NewDutyLocationID),
OriginDutyLocationID: *handlers.FmtUUID(updatedDutyLocation.ID),
IssueDate: handlers.FmtDate(issueDate),
ReportByDate: handlers.FmtDate(reportByDate),
DepartmentIndicator: &deptIndicator,
HasDependents: handlers.FmtBool(false),
SpouseHasProGear: handlers.FmtBool(false),
ServiceMemberID: handlers.FmtUUID(order.ServiceMemberID),
Grade: models.ServiceMemberGradeE4.Pointer(),
}

path := fmt.Sprintf("/orders/%v", order.ID.String())
req := httptest.NewRequest("PUT", path, nil)
req = suite.AuthenticateRequest(req, order.ServiceMember)

params := ordersop.UpdateOrdersParams{
HTTPRequest: req,
OrdersID: *handlers.FmtUUID(order.ID),
UpdateOrders: payload,
}

fakeS3 := storageTest.NewFakeS3Storage(true)
handlerConfig := suite.HandlerConfig()
handlerConfig.SetFileStorer(fakeS3)

handler := UpdateOrdersHandler{handlerConfig}

response := handler.Handle(params)

suite.IsType(&ordersop.UpdateOrdersOK{}, response)

okResponse := response.(*ordersop.UpdateOrdersOK)

suite.NoError(okResponse.Payload.Validate(strfmt.Default))
suite.Equal(string(newOrdersType), string(*okResponse.Payload.OrdersType))

fetchedOrder, err = models.FetchOrder(suite.DB(), order.ID)
suite.NoError(err)

fetchedPostalCode, err = fetchedOrder.GetOriginPostalCode(suite.DB())
suite.NoError(err)
fetchedGBLOC = *fetchedOrder.OriginDutyLocationGBLOC
suite.NoError(err)

suite.Equal("35023", fetchedPostalCode)
suite.Equal("CNNQ", fetchedGBLOC)
}

func (suite *HandlerSuite) TestEntitlementHelperFunc() {
orderGrade := internalmessages.OrderPayGrade("O-3")
int64Dependents := int64(2)
Expand Down
12 changes: 12 additions & 0 deletions pkg/models/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ const UniqueConstraintViolationOfficeUserOtherUniqueIDErrorString = "pq: duplica

// ErrInvalidMoveID is used if a argument is provided in cases where a move ID is provided, but may be malformed, empty, or nonexistent
var ErrInvalidMoveID = errors.New("INVALID_MOVE_ID")

// ErrInvalidOrderID is used if a argument is provided in cases where a order ID is provided, but may be malformed, empty, or nonexistent
var ErrInvalidOrderID = errors.New("INVALID_ORDER_ID")
WeatherfordAaron marked this conversation as resolved.
Show resolved Hide resolved

// ErrSqlRecordNotFound is used if an error is returned from the database indicating that no record was found
var ErrSqlRecordNotFound = errors.New("RECORD_NOT_FOUND")

// ErrMissingDestinationAddress is used if destination address is missing from the shipment
var ErrMissingDestinationAddress = errors.New("DESTINATION_ADDRESS_MISSING")

// ErrUnsupportedShipmentType is used if the shipment type is not supported by a method
var ErrUnsupportedShipmentType = errors.New("UNSUPPORTED_SHIPMENT_TYPE")
43 changes: 43 additions & 0 deletions pkg/models/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,49 @@ func (o *Order) CreateNewMove(db *pop.Connection, moveOptions MoveOptions) (*Mov
return createNewMove(db, *o, moveOptions)
}

/*
* GetOriginPostalCode returns the GBLOC for the postal code of the the origin duty location of the order.
*/
func (o Order) GetOriginPostalCode(db *pop.Connection) (string, error) {
// Since this requires looking up the order in the DB, the order must have an ID. This means, the order has to have been created first.
if uuid.UUID.IsNil(o.ID) {
return "", errors.WithMessage(ErrInvalidOrderID, "You must create the order in the DB before getting the origin GBLOC.")
}

err := db.Load(&o, "OriginDutyLocation.Address")
if err != nil {
if err.Error() == RecordNotFoundErrorString {
return "", errors.WithMessage(err, "No Origin Duty Location was found for the order ID "+o.ID.String())
}
return "", err
}

return o.OriginDutyLocation.Address.PostalCode, nil
}

/*
* GetOriginGBLOC returns the GBLOC for the postal code of the the origin duty location of the order.
*/
func (o Order) GetOriginGBLOC(db *pop.Connection) (string, error) {
// Since this requires looking up the order in the DB, the order must have an ID. This means, the order has to have been created first.
if uuid.UUID.IsNil(o.ID) {
return "", errors.WithMessage(ErrInvalidOrderID, "You must created the order in the DB before getting the destination GBLOC.")
}

originPostalCode, err := o.GetOriginPostalCode(db)
if err != nil {
return "", err
}

var originGBLOC PostalCodeToGBLOC
originGBLOC, err = FetchGBLOCForPostalCode(db, originPostalCode)
if err != nil {
return "", err
}

return originGBLOC.GBLOC, nil
}

// IsComplete checks if orders have all fields necessary to approve a move
func (o *Order) IsComplete() bool {

Expand Down
54 changes: 54 additions & 0 deletions pkg/testdatagen/scenario/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -10507,6 +10507,60 @@ func CreateNeedsServicesCounseling(appCtx appcontext.AppContext, ordersType inte
return move
}

/*
Create Needs Service Counseling in a non-default GBLOC - pass in orders with all required information, shipment type, destination type, locator
*/
func CreateNeedsServicesCounselingInOtherGBLOC(appCtx appcontext.AppContext, ordersType internalmessages.OrdersType, shipmentType models.MTOShipmentType, destinationType *models.DestinationType, locator string) models.Move {
db := appCtx.DB()
originDutyLocationAddress := factory.BuildAddress(db, []factory.Customization{
{
Model: models.Address{
PostalCode: "35023",
},
},
}, nil)
originDutyLocation := factory.BuildDutyLocation(db, []factory.Customization{
{
Model: models.DutyLocation{
Name: "Test Location",
AddressID: originDutyLocationAddress.ID,
},
},
}, nil)
order := factory.BuildOrder(db, []factory.Customization{
{
Model: originDutyLocation,
},
}, nil)
move := factory.BuildMove(db, []factory.Customization{
{
Model: order,
LinkOnly: true,
},
{
Model: models.Move{
Locator: locator,
Status: models.MoveStatusNeedsServiceCounseling,
},
},
}, nil)

factory.BuildMTOShipment(db, []factory.Customization{
{
Model: move,
LinkOnly: true,
},
{
Model: models.MTOShipment{
ShipmentType: shipmentType,
Status: models.MTOShipmentStatusSubmitted,
},
},
}, nil)

return move
}

func CreateNeedsServicesCounselingWithAmendedOrders(appCtx appcontext.AppContext, userUploader *uploader.UserUploader, ordersType internalmessages.OrdersType, shipmentType models.MTOShipmentType, destinationType *models.DestinationType, locator string) models.Move {
db := appCtx.DB()
submittedAt := time.Now()
Expand Down
3 changes: 3 additions & 0 deletions pkg/testdatagen/testharness/dispatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ var actionDispatcher = map[string]actionFunc{
"HHGMoveNeedsSC": func(appCtx appcontext.AppContext) testHarnessResponse {
return MakeHHGMoveNeedsSC(appCtx)
},
"HHGMoveNeedsSCOtherGBLOC": func(appCtx appcontext.AppContext) testHarnessResponse {
return MakeHHGMoveNeedsSCOtherGBLOC(appCtx)
},
"HHGMoveAsUSMCNeedsSC": func(appCtx appcontext.AppContext) testHarnessResponse {
return MakeHHGMoveNeedsServicesCounselingUSMC(appCtx)
},
Expand Down
Loading
Loading